parent
eb49dde076
commit
033f4624c8
|
@ -26,12 +26,12 @@ type Poll struct {
|
||||||
VoteCount int
|
VoteCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (poll *Poll) CastVote(optionIndex int, uid int, ipaddress string) error {
|
func (p *Poll) CastVote(optionIndex int, uid int, ip string) error {
|
||||||
return Polls.CastVote(optionIndex, poll.ID, uid, ipaddress) // TODO: Move the query into a pollStmts rather than having it in the store
|
return Polls.CastVote(optionIndex, p.ID, uid, ip) // TODO: Move the query into a pollStmts rather than having it in the store
|
||||||
}
|
}
|
||||||
|
|
||||||
func (poll *Poll) Copy() Poll {
|
func (p *Poll) Copy() Poll {
|
||||||
return *poll
|
return *p
|
||||||
}
|
}
|
||||||
|
|
||||||
type PollOption struct {
|
type PollOption struct {
|
||||||
|
@ -122,7 +122,7 @@ func (s *DefaultPollStore) Get(id int) (*Poll, error) {
|
||||||
// TODO: Optimise the query to avoid preparing it on the spot? Maybe, use knowledge of the most common IN() parameter counts?
|
// TODO: Optimise the query to avoid preparing it on the spot? Maybe, use knowledge of the most common IN() parameter counts?
|
||||||
// TODO: ID of 0 should always error?
|
// TODO: ID of 0 should always error?
|
||||||
func (s *DefaultPollStore) BulkGetMap(ids []int) (list map[int]*Poll, err error) {
|
func (s *DefaultPollStore) BulkGetMap(ids []int) (list map[int]*Poll, err error) {
|
||||||
var idCount = len(ids)
|
idCount := len(ids)
|
||||||
list = make(map[int]*Poll)
|
list = make(map[int]*Poll)
|
||||||
if idCount == 0 {
|
if idCount == 0 {
|
||||||
return list, nil
|
return list, nil
|
||||||
|
@ -159,21 +159,21 @@ func (s *DefaultPollStore) BulkGetMap(ids []int) (list map[int]*Poll, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
poll := &Poll{ID: 0}
|
p := &Poll{ID: 0}
|
||||||
var optionTxt []byte
|
var optionTxt []byte
|
||||||
err := rows.Scan(&poll.ID, &poll.ParentID, &poll.ParentTable, &poll.Type, &optionTxt, &poll.VoteCount)
|
err := rows.Scan(&p.ID, &p.ParentID, &p.ParentTable, &p.Type, &optionTxt, &p.VoteCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return list, err
|
return list, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(optionTxt, &poll.Options)
|
err = json.Unmarshal(optionTxt, &p.Options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return list, err
|
return list, err
|
||||||
}
|
}
|
||||||
poll.QuickOptions = s.unpackOptionsMap(poll.Options)
|
p.QuickOptions = s.unpackOptionsMap(p.Options)
|
||||||
s.cache.Set(poll)
|
s.cache.Set(p)
|
||||||
|
|
||||||
list[poll.ID] = poll
|
list[p.ID] = p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Did we miss any polls?
|
// Did we miss any polls?
|
||||||
|
@ -206,22 +206,22 @@ func (s *DefaultPollStore) BulkGetMap(ids []int) (list map[int]*Poll, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultPollStore) Reload(id int) error {
|
func (s *DefaultPollStore) Reload(id int) error {
|
||||||
poll := &Poll{ID: id}
|
p := &Poll{ID: id}
|
||||||
var optionTxt []byte
|
var optionTxt []byte
|
||||||
err := s.get.QueryRow(id).Scan(&poll.ParentID, &poll.ParentTable, &poll.Type, &optionTxt, &poll.VoteCount)
|
err := s.get.QueryRow(id).Scan(&p.ParentID, &p.ParentTable, &p.Type, &optionTxt, &p.VoteCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.cache.Remove(id)
|
s.cache.Remove(id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(optionTxt, &poll.Options)
|
err = json.Unmarshal(optionTxt, &p.Options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.cache.Remove(id)
|
s.cache.Remove(id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
poll.QuickOptions = s.unpackOptionsMap(poll.Options)
|
p.QuickOptions = s.unpackOptionsMap(p.Options)
|
||||||
_ = s.cache.Set(poll)
|
_ = s.cache.Set(p)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +258,6 @@ func (s *DefaultPollStore) Create(parent Pollable, pollType int, pollOptions map
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
lastID, err := res.LastInsertId()
|
lastID, err := res.LastInsertId()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -271,7 +270,8 @@ func (s *DefaultPollStore) Create(parent Pollable, pollType int, pollOptions map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return int(lastID), parent.SetPoll(int(lastID)) // TODO: Delete the poll (and options) if SetPoll fails
|
id = int(lastID)
|
||||||
|
return id, parent.SetPoll(id) // TODO: Delete the poll (and options) if SetPoll fails
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultPollStore) SetCache(cache PollCache) {
|
func (s *DefaultPollStore) SetCache(cache PollCache) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ package qgen
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var LogPrepares = true
|
var LogPrepares = true
|
||||||
|
@ -235,6 +236,10 @@ func (build *Accumulator) Select(table string) *AccSelectBuilder {
|
||||||
return &AccSelectBuilder{table, "", "", "", "", nil, nil, "", build}
|
return &AccSelectBuilder{table, "", "", "", "", nil, nil, "", build}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (build *Accumulator) Exists(tbl, col string) *AccSelectBuilder {
|
||||||
|
return build.Select(tbl).Columns(col).Where(col + "=?")
|
||||||
|
}
|
||||||
|
|
||||||
func (build *Accumulator) Insert(table string) *accInsertBuilder {
|
func (build *Accumulator) Insert(table string) *accInsertBuilder {
|
||||||
return &accInsertBuilder{table, "", "", build}
|
return &accInsertBuilder{table, "", "", build}
|
||||||
}
|
}
|
||||||
|
@ -242,3 +247,68 @@ func (build *Accumulator) Insert(table string) *accInsertBuilder {
|
||||||
func (build *Accumulator) Count(table string) *accCountBuilder {
|
func (build *Accumulator) Count(table string) *accCountBuilder {
|
||||||
return &accCountBuilder{table, "", "", nil, nil, "", build}
|
return &accCountBuilder{table, "", "", nil, nil, "", build}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SimpleModel struct {
|
||||||
|
delete *sql.Stmt
|
||||||
|
create *sql.Stmt
|
||||||
|
update *sql.Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (build *Accumulator) SimpleModel(tbl, colstr, primary string) SimpleModel {
|
||||||
|
var qlist, uplist string
|
||||||
|
for _, col := range strings.Split(colstr,",") {
|
||||||
|
qlist += "?,"
|
||||||
|
uplist += col + "=?,"
|
||||||
|
}
|
||||||
|
if len(qlist) > 0 {
|
||||||
|
qlist = qlist[0 : len(qlist)-1]
|
||||||
|
uplist = uplist[0 : len(uplist)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
where := primary + "=?"
|
||||||
|
return SimpleModel{
|
||||||
|
delete: build.Delete(tbl).Where(where).Prepare(),
|
||||||
|
create: build.Insert(tbl).Columns(colstr).Fields(qlist).Prepare(),
|
||||||
|
update: build.Update(tbl).Set(uplist).Where(where).Prepare(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m SimpleModel) Delete(keyVal interface{}) error {
|
||||||
|
_, err := m.delete.Exec(keyVal)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m SimpleModel) Update(args ...interface{}) error {
|
||||||
|
_, err := m.update.Exec(args...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m SimpleModel) Create(args ...interface{}) error {
|
||||||
|
_, err := m.create.Exec(args...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m SimpleModel) CreateID(args ...interface{}) (int, error) {
|
||||||
|
res, err := m.create.Exec(args...)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
lastID, err := res.LastInsertId()
|
||||||
|
return int(lastID), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (build *Accumulator) Model(table string) *accModelBuilder {
|
||||||
|
return &accModelBuilder{table,"",build}
|
||||||
|
}
|
||||||
|
|
||||||
|
type accModelBuilder struct {
|
||||||
|
table string
|
||||||
|
primary string
|
||||||
|
|
||||||
|
build *Accumulator
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *accModelBuilder) Primary(col string) *accModelBuilder {
|
||||||
|
b.primary = col
|
||||||
|
return b
|
||||||
|
}
|
|
@ -11,29 +11,29 @@ type prebuilder struct {
|
||||||
adapter Adapter
|
adapter Adapter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *prebuilder) Select(nlist ...string) *selectPrebuilder {
|
func (b *prebuilder) Select(nlist ...string) *selectPrebuilder {
|
||||||
name := optString(nlist, "")
|
name := optString(nlist, "")
|
||||||
return &selectPrebuilder{name, "", "", "", "", "", nil, nil, "", build.adapter}
|
return &selectPrebuilder{name, "", "", "", "", "", nil, nil, "", b.adapter}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *prebuilder) Count(nlist ...string) *selectPrebuilder {
|
func (b *prebuilder) Count(nlist ...string) *selectPrebuilder {
|
||||||
name := optString(nlist, "")
|
name := optString(nlist, "")
|
||||||
return &selectPrebuilder{name, "", "COUNT(*)", "", "", "", nil, nil, "", build.adapter}
|
return &selectPrebuilder{name, "", "COUNT(*)", "", "", "", nil, nil, "", b.adapter}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *prebuilder) Insert(nlist ...string) *insertPrebuilder {
|
func (b *prebuilder) Insert(nlist ...string) *insertPrebuilder {
|
||||||
name := optString(nlist, "")
|
name := optString(nlist, "")
|
||||||
return &insertPrebuilder{name, "", "", "", build.adapter}
|
return &insertPrebuilder{name, "", "", "", b.adapter}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *prebuilder) Update(nlist ...string) *updatePrebuilder {
|
func (b *prebuilder) Update(nlist ...string) *updatePrebuilder {
|
||||||
name := optString(nlist, "")
|
name := optString(nlist, "")
|
||||||
return &updatePrebuilder{name, "", "", "", nil, nil, build.adapter}
|
return &updatePrebuilder{name, "", "", "", nil, nil, b.adapter}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *prebuilder) Delete(nlist ...string) *deletePrebuilder {
|
func (b *prebuilder) Delete(nlist ...string) *deletePrebuilder {
|
||||||
name := optString(nlist, "")
|
name := optString(nlist, "")
|
||||||
return &deletePrebuilder{name, "", "", nil, build.adapter}
|
return &deletePrebuilder{name, "", "", nil, b.adapter}
|
||||||
}
|
}
|
||||||
|
|
||||||
type deletePrebuilder struct {
|
type deletePrebuilder struct {
|
||||||
|
|
|
@ -24,49 +24,49 @@ type TransactionBuilder struct {
|
||||||
textToStmt map[string]*transactionStmt
|
textToStmt map[string]*transactionStmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *TransactionBuilder) SimpleDelete(table string, where string) (stmt *sql.Stmt, err error) {
|
func (b *TransactionBuilder) SimpleDelete(table string, where string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleDelete("", table, where)
|
res, err := b.adapter.SimpleDelete("", table, where)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stmt, err
|
return stmt, err
|
||||||
}
|
}
|
||||||
return build.tx.Prepare(res)
|
return b.tx.Prepare(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quick* versions refer to it being quick to type not the performance. For performance critical transactions, you might want to use the Simple* methods or the *Tx methods on the main builder. Alternate suggestions for names are welcome :)
|
// Quick* versions refer to it being quick to type not the performance. For performance critical transactions, you might want to use the Simple* methods or the *Tx methods on the main builder. Alternate suggestions for names are welcome :)
|
||||||
func (build *TransactionBuilder) QuickDelete(table string, where string) *transactionStmt {
|
func (b *TransactionBuilder) QuickDelete(table string, where string) *transactionStmt {
|
||||||
res, err := build.adapter.SimpleDelete("", table, where)
|
res, err := b.adapter.SimpleDelete("", table, where)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newTransactionStmt(nil, err)
|
return newTransactionStmt(nil, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt, ok := build.textToStmt[res]
|
stmt, ok := b.textToStmt[res]
|
||||||
if ok {
|
if ok {
|
||||||
return stmt
|
return stmt
|
||||||
}
|
}
|
||||||
stmt = newTransactionStmt(build.tx.Prepare(res))
|
stmt = newTransactionStmt(b.tx.Prepare(res))
|
||||||
build.textToStmt[res] = stmt
|
b.textToStmt[res] = stmt
|
||||||
return stmt
|
return stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *TransactionBuilder) SimpleInsert(table string, columns string, fields string) (stmt *sql.Stmt, err error) {
|
func (b *TransactionBuilder) SimpleInsert(table string, columns string, fields string) (stmt *sql.Stmt, err error) {
|
||||||
res, err := build.adapter.SimpleInsert("", table, columns, fields)
|
res, err := b.adapter.SimpleInsert("", table, columns, fields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stmt, err
|
return stmt, err
|
||||||
}
|
}
|
||||||
return build.tx.Prepare(res)
|
return b.tx.Prepare(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (build *TransactionBuilder) QuickInsert(table string, where string) *transactionStmt {
|
func (b *TransactionBuilder) QuickInsert(table string, where string) *transactionStmt {
|
||||||
res, err := build.adapter.SimpleDelete("", table, where)
|
res, err := b.adapter.SimpleDelete("", table, where)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newTransactionStmt(nil, err)
|
return newTransactionStmt(nil, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt, ok := build.textToStmt[res]
|
stmt, ok := b.textToStmt[res]
|
||||||
if ok {
|
if ok {
|
||||||
return stmt
|
return stmt
|
||||||
}
|
}
|
||||||
stmt = newTransactionStmt(build.tx.Prepare(res))
|
stmt = newTransactionStmt(b.tx.Prepare(res))
|
||||||
build.textToStmt[res] = stmt
|
b.textToStmt[res] = stmt
|
||||||
return stmt
|
return stmt
|
||||||
}
|
}
|
||||||
|
|
|
@ -399,7 +399,7 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
||||||
elemStr = elemStr[:len(elemStr)-1]
|
elemStr = elemStr[:len(elemStr)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write([]byte(`{"success":"1","elems":{` + elemStr + `}}`))
|
w.Write([]byte(`{"success":1,"elems":{` + elemStr + `}}`))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue