🎉🚀 May the concensus be with us!
This commit is contained in:
commit
48328e7db2
33 changed files with 4051 additions and 0 deletions
21
store/db.go
Normal file
21
store/db.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
const file = "./govote.db"
|
||||
|
||||
var db *sql.DB
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
if db, err = sql.Open("sqlite3", file); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
initCreateTables(db)
|
||||
initStmts(db)
|
||||
}
|
||||
|
||||
110
store/handler.go
Normal file
110
store/handler.go
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.c-base.org/baccenfutter/govote/voting"
|
||||
"code.c-base.org/baccenfutter/govote/voting/quorum"
|
||||
"code.c-base.org/baccenfutter/govote/voting/threshold"
|
||||
"code.c-base.org/baccenfutter/govote/voting/vote"
|
||||
)
|
||||
|
||||
func NewVoting(
|
||||
id string,
|
||||
r string,
|
||||
d time.Time,
|
||||
q quorum.Quorum,
|
||||
t threshold.Threshold,
|
||||
e []string,
|
||||
a bool,
|
||||
) error {
|
||||
electors := strings.Join(e, ";")
|
||||
if _, err := votingInsert.Exec(id, r, d.String(), q.String(), t.String(), electors, a); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetVoting(id string) (*voting.Voting, error) {
|
||||
result := votingSelect.QueryRow(id)
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("not found: %s", id)
|
||||
}
|
||||
var (
|
||||
err error
|
||||
r string
|
||||
d time.Time
|
||||
q quorum.Quorum
|
||||
t threshold.Threshold
|
||||
e []string
|
||||
a bool
|
||||
dbDeadline string
|
||||
dbQuorum string
|
||||
dbThreshold string
|
||||
dbElectors string
|
||||
)
|
||||
if err := result.Scan(&r, &dbDeadline, &dbQuorum, &dbThreshold, &dbElectors, &a); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if d, err = time.Parse("2006-01-02 15:04:05 -0700 MST", dbDeadline); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if q, err = quorum.FromString(dbQuorum); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if t, err = threshold.FromString(dbThreshold); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
e = strings.Split(dbElectors, " ")
|
||||
|
||||
votes, err := getVotes(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v := voting.NewVotingWithVotes(id, r, d, q, t, e, a, votes)
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func PlaceVote(id, votingID, elector string, choice vote.Choice) error {
|
||||
if _, err := voteInsert.Exec(id, votingID, elector, choice.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getVotes(id string) ([]vote.Vote, error) {
|
||||
result, err := voteSelect.Query(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
e string
|
||||
c vote.Choice
|
||||
ts time.Time
|
||||
dbChoice string
|
||||
dbTimestamp string
|
||||
votes = []vote.Vote{}
|
||||
)
|
||||
for result.Next() {
|
||||
if err = result.Scan(&e, &dbChoice, &dbTimestamp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c, err = vote.ChoiceFromString(dbChoice); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ts, err = time.Parse("2006-01-02 15:04:05", dbTimestamp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := vote.NewVoteWithTimestamp(e, c, ts)
|
||||
votes = append(votes, v)
|
||||
}
|
||||
|
||||
return votes, nil
|
||||
}
|
||||
136
store/prepared.go
Normal file
136
store/prepared.go
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
package store
|
||||
|
||||
import "database/sql"
|
||||
|
||||
var (
|
||||
votingInsert *sql.Stmt
|
||||
votingSelect *sql.Stmt
|
||||
voteEligible *sql.Stmt
|
||||
voteInsert *sql.Stmt
|
||||
voteSelect *sql.Stmt
|
||||
)
|
||||
|
||||
func initCreateTables(db *sql.DB) {
|
||||
var err error
|
||||
createTables := `
|
||||
CREATE TABLE IF NOT EXISTS voting (
|
||||
id TEXT PRIMARY KEY,
|
||||
referendum TEXT NOT NULL,
|
||||
created DATETIME WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deadline DATETIME WITHOUT TIME ZONE NOT NULL,
|
||||
quorum TEXT NOT NULL DEFAULT 'SIMPLE',
|
||||
threshold TEXT NOT NULL DEFAULT 'SIMPLE',
|
||||
electors TEXT,
|
||||
anonymous BOOL NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vote (
|
||||
id BLOB PRIMARY KEY,
|
||||
voting TEXT NOT NULL,
|
||||
elector TEXT NOT NULL,
|
||||
choice TEXT NOT NULL,
|
||||
timestamp DATETIME WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY(voting) REFERENCES voting(id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS vote_voting ON vote ( voting );
|
||||
`
|
||||
|
||||
if _, err = db.Exec(createTables); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initStmts(db *sql.DB) {
|
||||
initStmtVotingInsert(db)
|
||||
initStmtVotingSelect(db)
|
||||
|
||||
initStmtVoteEligible(db)
|
||||
initStmtVoteInsert(db)
|
||||
initStmtVoteSelect(db)
|
||||
}
|
||||
|
||||
func initStmtVotingInsert(db *sql.DB) {
|
||||
var err error
|
||||
if votingInsert, err = db.Prepare(`
|
||||
INSERT INTO voting (
|
||||
id,
|
||||
referendum,
|
||||
deadline,
|
||||
quorum,
|
||||
threshold,
|
||||
electors,
|
||||
anonymous
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?);
|
||||
`); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initStmtVotingSelect(db *sql.DB) {
|
||||
var err error
|
||||
if votingSelect, err = db.Prepare(`
|
||||
SELECT
|
||||
referendum,
|
||||
deadline,
|
||||
quorum,
|
||||
threshold,
|
||||
electors,
|
||||
anonymous
|
||||
FROM voting
|
||||
WHERE id = ?;
|
||||
`); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initStmtVoteEligible(db *sql.DB) {
|
||||
var err error
|
||||
if voteEligible, err = db.Prepare(`
|
||||
SELECT
|
||||
id,
|
||||
referendum,
|
||||
created,
|
||||
deadline,
|
||||
quorum,
|
||||
threshold
|
||||
FROM voting
|
||||
WHERE
|
||||
id = ?
|
||||
AND deadline > datetime('now')
|
||||
AND (
|
||||
electors IS NULL
|
||||
OR ',' || electors || ',' LIKE '%,' || ? || ',%'
|
||||
)
|
||||
LIMIT 1;
|
||||
`); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initStmtVoteInsert(db *sql.DB) {
|
||||
var err error
|
||||
if voteInsert, err = db.Prepare(`
|
||||
INSERT INTO vote (
|
||||
id, voting, elector, choice
|
||||
) VALUES (
|
||||
?, ?, ?, ?
|
||||
);
|
||||
`); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initStmtVoteSelect(db *sql.DB) {
|
||||
var err error
|
||||
if voteSelect, err = db.Prepare(`
|
||||
SELECT
|
||||
elector,
|
||||
choice,
|
||||
timestamp
|
||||
FROM vote
|
||||
WHERE voting = ?;
|
||||
`); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue