Experiment with the accumulator.
Less boilerplate.
This commit is contained in:
parent
eb49dde076
commit
033f4624c8
@ -26,12 +26,12 @@ type Poll struct {
|
||||
VoteCount int
|
||||
}
|
||||
|
||||
func (poll *Poll) CastVote(optionIndex int, uid int, ipaddress string) error {
|
||||
return Polls.CastVote(optionIndex, poll.ID, uid, ipaddress) // TODO: Move the query into a pollStmts rather than having it in the store
|
||||
func (p *Poll) CastVote(optionIndex int, uid int, ip string) error {
|
||||
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 {
|
||||
return *poll
|
||||
func (p *Poll) Copy() Poll {
|
||||
return *p
|
||||
}
|
||||
|
||||
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: ID of 0 should always 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)
|
||||
if idCount == 0 {
|
||||
return list, nil
|
||||
@ -159,21 +159,21 @@ func (s *DefaultPollStore) BulkGetMap(ids []int) (list map[int]*Poll, err error)
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
poll := &Poll{ID: 0}
|
||||
p := &Poll{ID: 0}
|
||||
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 {
|
||||
return list, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(optionTxt, &poll.Options)
|
||||
err = json.Unmarshal(optionTxt, &p.Options)
|
||||
if err != nil {
|
||||
return list, err
|
||||
}
|
||||
poll.QuickOptions = s.unpackOptionsMap(poll.Options)
|
||||
s.cache.Set(poll)
|
||||
p.QuickOptions = s.unpackOptionsMap(p.Options)
|
||||
s.cache.Set(p)
|
||||
|
||||
list[poll.ID] = poll
|
||||
list[p.ID] = p
|
||||
}
|
||||
|
||||
// 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 {
|
||||
poll := &Poll{ID: id}
|
||||
p := &Poll{ID: id}
|
||||
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 {
|
||||
s.cache.Remove(id)
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(optionTxt, &poll.Options)
|
||||
err = json.Unmarshal(optionTxt, &p.Options)
|
||||
if err != nil {
|
||||
s.cache.Remove(id)
|
||||
return err
|
||||
}
|
||||
|
||||
poll.QuickOptions = s.unpackOptionsMap(poll.Options)
|
||||
_ = s.cache.Set(poll)
|
||||
p.QuickOptions = s.unpackOptionsMap(p.Options)
|
||||
_ = s.cache.Set(p)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -258,7 +258,6 @@ func (s *DefaultPollStore) Create(parent Pollable, pollType int, pollOptions map
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
lastID, err := res.LastInsertId()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@ -270,8 +269,9 @@ func (s *DefaultPollStore) Create(parent Pollable, pollType int, pollOptions map
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -4,6 +4,7 @@ package qgen
|
||||
import (
|
||||
"database/sql"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var LogPrepares = true
|
||||
@ -235,6 +236,10 @@ func (build *Accumulator) Select(table string) *AccSelectBuilder {
|
||||
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 {
|
||||
return &accInsertBuilder{table, "", "", build}
|
||||
}
|
||||
@ -242,3 +247,68 @@ func (build *Accumulator) Insert(table string) *accInsertBuilder {
|
||||
func (build *Accumulator) Count(table string) *accCountBuilder {
|
||||
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
|
||||
}
|
||||
|
||||
func (build *prebuilder) Select(nlist ...string) *selectPrebuilder {
|
||||
func (b *prebuilder) Select(nlist ...string) *selectPrebuilder {
|
||||
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, "")
|
||||
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, "")
|
||||
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, "")
|
||||
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, "")
|
||||
return &deletePrebuilder{name, "", "", nil, build.adapter}
|
||||
return &deletePrebuilder{name, "", "", nil, b.adapter}
|
||||
}
|
||||
|
||||
type deletePrebuilder struct {
|
||||
|
@ -24,49 +24,49 @@ type TransactionBuilder struct {
|
||||
textToStmt map[string]*transactionStmt
|
||||
}
|
||||
|
||||
func (build *TransactionBuilder) SimpleDelete(table string, where string) (stmt *sql.Stmt, err error) {
|
||||
res, err := build.adapter.SimpleDelete("", table, where)
|
||||
func (b *TransactionBuilder) SimpleDelete(table string, where string) (stmt *sql.Stmt, err error) {
|
||||
res, err := b.adapter.SimpleDelete("", table, where)
|
||||
if err != nil {
|
||||
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 :)
|
||||
func (build *TransactionBuilder) QuickDelete(table string, where string) *transactionStmt {
|
||||
res, err := build.adapter.SimpleDelete("", table, where)
|
||||
func (b *TransactionBuilder) QuickDelete(table string, where string) *transactionStmt {
|
||||
res, err := b.adapter.SimpleDelete("", table, where)
|
||||
if err != nil {
|
||||
return newTransactionStmt(nil, err)
|
||||
}
|
||||
|
||||
stmt, ok := build.textToStmt[res]
|
||||
stmt, ok := b.textToStmt[res]
|
||||
if ok {
|
||||
return stmt
|
||||
}
|
||||
stmt = newTransactionStmt(build.tx.Prepare(res))
|
||||
build.textToStmt[res] = stmt
|
||||
stmt = newTransactionStmt(b.tx.Prepare(res))
|
||||
b.textToStmt[res] = stmt
|
||||
return stmt
|
||||
}
|
||||
|
||||
func (build *TransactionBuilder) SimpleInsert(table string, columns string, fields string) (stmt *sql.Stmt, err error) {
|
||||
res, err := build.adapter.SimpleInsert("", table, columns, fields)
|
||||
func (b *TransactionBuilder) SimpleInsert(table string, columns string, fields string) (stmt *sql.Stmt, err error) {
|
||||
res, err := b.adapter.SimpleInsert("", table, columns, fields)
|
||||
if err != nil {
|
||||
return stmt, err
|
||||
}
|
||||
return build.tx.Prepare(res)
|
||||
return b.tx.Prepare(res)
|
||||
}
|
||||
|
||||
func (build *TransactionBuilder) QuickInsert(table string, where string) *transactionStmt {
|
||||
res, err := build.adapter.SimpleDelete("", table, where)
|
||||
func (b *TransactionBuilder) QuickInsert(table string, where string) *transactionStmt {
|
||||
res, err := b.adapter.SimpleDelete("", table, where)
|
||||
if err != nil {
|
||||
return newTransactionStmt(nil, err)
|
||||
}
|
||||
|
||||
stmt, ok := build.textToStmt[res]
|
||||
stmt, ok := b.textToStmt[res]
|
||||
if ok {
|
||||
return stmt
|
||||
}
|
||||
stmt = newTransactionStmt(build.tx.Prepare(res))
|
||||
build.textToStmt[res] = stmt
|
||||
stmt = newTransactionStmt(b.tx.Prepare(res))
|
||||
b.textToStmt[res] = stmt
|
||||
return stmt
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
|
||||
elemStr = elemStr[:len(elemStr)-1]
|
||||
}
|
||||
|
||||
w.Write([]byte(`{"success":"1","elems":{` + elemStr + `}}`))
|
||||
w.Write([]byte(`{"success":1,"elems":{` + elemStr + `}}`))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user