adding project to github
This commit is contained in:
184
api/account/member.go
Normal file
184
api/account/member.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
|
||||
"../database"
|
||||
"github.com/twinj/uuid"
|
||||
)
|
||||
|
||||
type Account struct {
|
||||
Member Member `json:"member"`
|
||||
User User `json:"user"`
|
||||
Sso []Sso `json:"sso"`
|
||||
}
|
||||
|
||||
type Member struct {
|
||||
Id string `json:"id" db:"id"`
|
||||
Name string `json:"name" db:"name"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Id string `json:"id" db:"id"`
|
||||
Username string `json:"username" db:"username"`
|
||||
Password string `json:"password" db:"password"`
|
||||
}
|
||||
|
||||
type Sso struct {
|
||||
Id string `json:"id" db:"id"`
|
||||
Token string `json:"token" db:"token"`
|
||||
SsoTypeId string `json:"ssoTypeId" db:"ssoTypeId"`
|
||||
}
|
||||
|
||||
type SsoType struct {
|
||||
Id string `json:"id" db:"id"`
|
||||
Source string `json:"source" db:"source"`
|
||||
}
|
||||
|
||||
func Login(account *Account) error {
|
||||
selectStatement := "SELECT BIN_TO_UUID(`member`.`id`) AS memberId " +
|
||||
", `member`.`name` " +
|
||||
", COALESCE(BIN_TO_UUID(`user`.`id`), '') AS userId " +
|
||||
", COALESCE(`user`.`username`, '') AS username " +
|
||||
", COALESCE(`user`.`password`, '') AS password " +
|
||||
", COALESCE(BIN_TO_UUID(`sso`.`id`), '') AS ssoId " +
|
||||
", COALESCE(`sso`.`token`, '') AS token " +
|
||||
", COALESCE(BIN_TO_UUID(`sso`.`ssoTypeId`), '') AS ssoTypeId " +
|
||||
"FROM `member` " +
|
||||
"LEFT JOIN `user` ON `member`.`id` = `user`.`memberId` " +
|
||||
"LEFT JOIN `sso` ON `member`.`id` = `sso`.`memberId` "
|
||||
|
||||
whereClause := ""
|
||||
vars := make([]interface{}, 2)
|
||||
errorMessage := ""
|
||||
|
||||
if &account.User != nil && &account.User.Username != nil && &account.User.Password != nil && account.User.Password != "" {
|
||||
whereClause = "WHERE LOWER(`user`.`username`) = LOWER(?) " +
|
||||
"AND `user`.`password` = ?"
|
||||
|
||||
vars[0] = account.User.Username
|
||||
vars[1] = account.User.Password
|
||||
|
||||
errorMessage = "invalid username or password"
|
||||
account.Sso = make([]Sso, 1)
|
||||
account.Sso[0] = Sso{}
|
||||
} else if &account.Sso != nil && len(account.Sso) == 1 && account.Sso[0].Token != "" && &account.Sso[0].SsoTypeId != nil && account.Sso[0].SsoTypeId != "" {
|
||||
whereClause = "WHERE `sso`.`token` = ? " +
|
||||
"AND `sso`.`ssoTypeId` = ?"
|
||||
|
||||
vars[0] = account.Sso[0].Token
|
||||
vars[1] = account.Sso[0].SsoTypeId
|
||||
errorMessage = "invalid sso credentials"
|
||||
} else {
|
||||
return errors.New("account must have either a user or an sso login")
|
||||
}
|
||||
|
||||
result, err := database.DB.Query(selectStatement+whereClause, vars...)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !result.Next() {
|
||||
return errors.New(errorMessage)
|
||||
}
|
||||
|
||||
err = result.Scan(&account.Member.Id, &account.Member.Name, &account.User.Id, &account.User.Username, &account.User.Password, &account.Sso[0].Id, &account.Sso[0].Token, &account.Sso[0].SsoTypeId)
|
||||
return err
|
||||
}
|
||||
|
||||
func Create(account *Account) error {
|
||||
if account == nil || &account.Member == nil || account.Member.Name == "" {
|
||||
return errors.New("account needs to have a name")
|
||||
} else if &account.User != nil && &account.User.Username != nil && &account.User.Password != nil && account.User.Password != "" {
|
||||
matched, err := regexp.MatchString("(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\\])", account.User.Username)
|
||||
if err == nil && matched {
|
||||
return createViaUser(account)
|
||||
} else {
|
||||
return errors.New("username must be an email address")
|
||||
}
|
||||
} else if &account.Sso != nil && len(account.Sso) == 1 && account.Sso[0].Token != "" && &account.Sso[0].SsoTypeId != nil && account.Sso[0].SsoTypeId != "" {
|
||||
return createViaSso(account)
|
||||
} else {
|
||||
return errors.New("account must have either a user or an sso login")
|
||||
}
|
||||
}
|
||||
|
||||
func createViaUser(account *Account) error {
|
||||
account.Member.Id = uuid.NewV4().String()
|
||||
account.User.Id = uuid.NewV4().String()
|
||||
|
||||
exists, err := database.Exists("user", "username", account.User.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if exists {
|
||||
return errors.New("username unavailable")
|
||||
}
|
||||
|
||||
err = database.Insert("member", account.Member, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = database.Insert("user", account.User, []string{"memberId"}, []interface{}{account.Member.Id})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func createViaSso(account *Account) error {
|
||||
account.Member.Id = uuid.NewV4().String()
|
||||
account.Sso[0].Id = uuid.NewV4().String()
|
||||
|
||||
result, err := database.DB.Query("SELECT BIN_TO_UUID(`id`) AS id, `source` FROM `ssoType` WHERE `id` = UUID_TO_BIN(?);", account.Sso[0].SsoTypeId)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !result.Next() {
|
||||
return errors.New("no sso type with this id")
|
||||
}
|
||||
|
||||
result, err = database.DB.Query("SELECT COUNT(`id`) AS c FROM `sso` WHERE `token` = ? AND `ssoTypeId` = UUID_TO_BIN(?);", account.Sso[0].Token, account.Sso[0].SsoTypeId)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !result.Next() {
|
||||
return errors.New("query produced no results")
|
||||
}
|
||||
|
||||
var c int
|
||||
err = result.Scan(&c)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if c != 0 {
|
||||
return errors.New("this sso already exists")
|
||||
}
|
||||
|
||||
err = database.Insert("member", account.Member, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = database.Insert("sso", account.Sso[0], []string{"memberId"}, []interface{}{account.Member.Id})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func SsoTypes() ([]SsoType, error) {
|
||||
result, err := database.DB.Query("SELECT BIN_TO_UUID(`id`) AS id, `source` FROM `ssoType`")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ssoTypes := make([]SsoType,)
|
||||
for result.Next() {
|
||||
|
||||
}
|
||||
|
||||
var c int
|
||||
err = result.Scan(&c)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if c != 0 {
|
||||
return errors.New("this sso already exists")
|
||||
}
|
||||
}
|
||||
113
api/database/connection.go
Normal file
113
api/database/connection.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var DB *sql.DB
|
||||
|
||||
func Insert(table string, object interface{}, additionalColumns []string, additionalValues []interface{}) error {
|
||||
return upsert(table, object, false, additionalColumns, additionalValues)
|
||||
}
|
||||
|
||||
func Update(table string, object interface{}, additionalColumns []string, additionalValues []interface{}) error {
|
||||
return upsert(table, object, true, additionalColumns, additionalValues)
|
||||
}
|
||||
|
||||
func upsert(table string, object interface{}, isUpdate bool, additionalColumns []string, additionalValues []interface{}) error {
|
||||
statement := "INSERT INTO `" + table + "` (" // col1, col2
|
||||
values := ") VALUES (" // ?, ?
|
||||
v := reflect.ValueOf(object)
|
||||
|
||||
if isUpdate {
|
||||
statement = "UPDATE `" + table + "` SET"
|
||||
values = ""
|
||||
}
|
||||
|
||||
for i := 0; i < v.Type().NumField(); i++ {
|
||||
if v.Field(i).CanInterface() {
|
||||
additionalColumns = append(additionalColumns, getColumn(v.Type().Field(i)))
|
||||
additionalValues = append(additionalValues, v.Field(i).Interface())
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(additionalColumns); i++ {
|
||||
if i > 0 {
|
||||
if !isUpdate {
|
||||
statement += ", "
|
||||
}
|
||||
values += ", "
|
||||
}
|
||||
column := additionalColumns[i]
|
||||
value := "?"
|
||||
|
||||
if column == "id" || strings.HasSuffix(column, "Id") {
|
||||
value = "UUID_TO_BIN(?)"
|
||||
}
|
||||
|
||||
if isUpdate {
|
||||
values += "`" + column + "` = " + value
|
||||
|
||||
if column == "id" {
|
||||
additionalValues = append(additionalValues, additionalValues[i])
|
||||
}
|
||||
} else {
|
||||
statement += "`" + column + "`"
|
||||
values += value
|
||||
}
|
||||
|
||||
}
|
||||
if isUpdate {
|
||||
values += " WHERE `id` = UUID_TO_BIN(?);"
|
||||
} else {
|
||||
values += ");"
|
||||
}
|
||||
|
||||
rows, err := DB.Exec(statement+values, additionalValues...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n, err := rows.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
} else if n != 1 {
|
||||
operation := "insert to"
|
||||
if isUpdate {
|
||||
operation = "update"
|
||||
}
|
||||
return errors.New("failed to " + operation + " " + table)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getColumn(field reflect.StructField) string {
|
||||
column, ok := field.Tag.Lookup("db")
|
||||
if !ok {
|
||||
column = field.Name
|
||||
}
|
||||
return column
|
||||
}
|
||||
|
||||
func Exists(table string, column string, value interface{}) (bool, error) {
|
||||
result, err := DB.Query("SELECT COUNT(`id`) AS c FROM `"+table+"` WHERE `"+column+"` = ?;", value)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
} else if !result.Next() {
|
||||
return false, errors.New("query produced no results")
|
||||
}
|
||||
|
||||
var c int
|
||||
err = result.Scan(&c)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return c > 0, nil
|
||||
}
|
||||
65
api/endpoint/account.go
Normal file
65
api/endpoint/account.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package endpoint
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"../account"
|
||||
"../util"
|
||||
)
|
||||
|
||||
//TODO do not return passwords and sso tokens
|
||||
|
||||
func CreateAccount(w http.ResponseWriter, req *http.Request) {
|
||||
var acc account.Account
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&acc)
|
||||
|
||||
if err != nil {
|
||||
util.ErrorResponse(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
err = account.Create(&acc)
|
||||
|
||||
if err != nil {
|
||||
util.ErrorResponse(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(acc)
|
||||
|
||||
if err != nil {
|
||||
util.ErrorResponse(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(jsonData)
|
||||
}
|
||||
|
||||
func Login(w http.ResponseWriter, req *http.Request) {
|
||||
var acc account.Account
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&acc)
|
||||
|
||||
if err != nil {
|
||||
util.ErrorResponse(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
err = account.Login(&acc)
|
||||
|
||||
if err != nil {
|
||||
util.ErrorResponse(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(acc)
|
||||
|
||||
if err != nil {
|
||||
util.ErrorResponse(err, w)
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(jsonData)
|
||||
}
|
||||
56
api/league/league.go
Normal file
56
api/league/league.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package league
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"../database"
|
||||
"github.com/twinj/uuid"
|
||||
)
|
||||
|
||||
type League struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Public bool `json:"public"`
|
||||
}
|
||||
|
||||
func createLeague(league *League) error {
|
||||
if league == nil || &league.Name == nil || league.Name == "" {
|
||||
return errors.New("league needs to have a name")
|
||||
}
|
||||
|
||||
//todo use db.exists
|
||||
result, err := database.DB.Query("SELECT COUNT(`id`) AS c FROM `league` WHERE `name` = ?;", league.Name)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !result.Next() {
|
||||
return errors.New("query produced no results")
|
||||
}
|
||||
|
||||
var c int
|
||||
err = result.Scan(&c)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if c != 0 {
|
||||
return errors.New("league name unavailable")
|
||||
}
|
||||
|
||||
league.Id = uuid.NewV4().String()
|
||||
if &league.Public == nil {
|
||||
league.Public = true
|
||||
}
|
||||
|
||||
//todo use db.insert
|
||||
rows, err := database.DB.Exec("INSERT INTO `league` (`id`, `name`, `public`) VALUES (UUID_TO_BIN(?), ?, ?);", league.Id, league.Name, league.Public)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
n, err := rows.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
} else if n != 1 {
|
||||
return errors.New("failed to insert member")
|
||||
}
|
||||
}
|
||||
28
api/main.go
Normal file
28
api/main.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"net/http"
|
||||
|
||||
"./database"
|
||||
"./endpoint"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func main() {
|
||||
//todo get connection string based on zone
|
||||
db, err := sql.Open("mysql", "root:Se4Q2Lp-3587@tcp(localhost)/baseball")
|
||||
if err != nil {
|
||||
//todo handle it (fatal, can't continue.)
|
||||
}
|
||||
database.DB = db
|
||||
defer database.DB.Close()
|
||||
|
||||
router := mux.NewRouter()
|
||||
|
||||
router.HandleFunc("/account/create", endpoint.CreateAccount).Methods("POST")
|
||||
router.HandleFunc("/account/login", endpoint.Login).Methods("POST")
|
||||
|
||||
http.ListenAndServe(":8080", router)
|
||||
}
|
||||
12
api/util/log.go
Normal file
12
api/util/log.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ErrorResponse(err error, w http.ResponseWriter) {
|
||||
if err != nil {
|
||||
w.Write([]byte("{\"error\":\"" + strings.Replace(err.Error(), "\"", "\\\"", -1) + "\"}"))
|
||||
}
|
||||
}
|
||||
13
data/README.md
Normal file
13
data/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# How to use these files
|
||||
|
||||
Each `sql` script in this folder needs to be executed using the appropriate database.
|
||||
Due to foreign key constraints, a proper order must be followed.
|
||||
`_MASTER_.sql` has the proper order, and can be executed like so:
|
||||
|
||||
```sql
|
||||
use baseball;
|
||||
source /path/to/_MASTER_.sql;
|
||||
```
|
||||
|
||||
Which will then execute each script in order.
|
||||
Then, verify that each statement was successful.
|
||||
19
data/_MASTER_.sql
Normal file
19
data/_MASTER_.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\league.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\member.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\role.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\leagueMember.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\team.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\position.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\player.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\teamPlayer.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\trade.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\injury.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\invitation.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\statistic.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\draft.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\draftPick.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\notificationTemplate.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\notification.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\user.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\ssoType.sql
|
||||
source C:\Users\Bronson\Desktop\baseballApp\data\sso.sql
|
||||
29
data/draft.sql
Normal file
29
data/draft.sql
Normal file
@@ -0,0 +1,29 @@
|
||||
CREATE TABLE IF NOT EXISTS `draft` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`leagueId` BINARY(16) NOT NULL,
|
||||
`turn` BINARY(16) NOT NULL, -- this is the leagueMemberId of whose turn it is. not foreign key so if the member is removed, we can go: this person doesn't exist, so it's the next member after.
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
FOREIGN KEY(`leagueId`) REFERENCES `league`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertDraftTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertDraftTrigger` BEFORE INSERT ON `draft`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateDraftTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateDraftTrigger` BEFORE UPDATE ON `draft`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
34
data/draftPick.sql
Normal file
34
data/draftPick.sql
Normal file
@@ -0,0 +1,34 @@
|
||||
CREATE TABLE IF NOT EXISTS `draftPick` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`draftId` BINARY(16) NOT NULL,
|
||||
`leagueMemberId` BINARY(16) NOT NULL,
|
||||
`order` INT(11) NOT NULL,
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
UNIQUE (`draftId`, `leagueMemberId`),
|
||||
UNIQUE (`leagueMemberId`, `order`),
|
||||
|
||||
FOREIGN KEY(`draftId`) REFERENCES `draft`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY(`leagueMemberId`) REFERENCES `leagueMember`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertDraftPickTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertDraftPickTrigger` BEFORE INSERT ON `draftPick`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateDraftPickTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateDraftPickTrigger` BEFORE UPDATE ON `draftPick`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
30
data/injury.sql
Normal file
30
data/injury.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
CREATE TABLE IF NOT EXISTS `injury` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`playerId` BINARY(16) NOT NULL,
|
||||
`reason` VARCHAR(1024), -- this and below are from fantasybaseballnerd.com
|
||||
`notes` VARCHAR(2048),
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
FOREIGN KEY(`playerId`) REFERENCES `player`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertInjuryTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertInjuryTrigger` BEFORE INSERT ON `injury`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateInjuryTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateInjuryTrigger` BEFORE UPDATE ON `injury`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
33
data/invitation.sql
Normal file
33
data/invitation.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
CREATE TABLE IF NOT EXISTS `invitation` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`leagueId` BINARY(16) NOT NULL,
|
||||
`memberId` BINARY(16) NOT NULL,
|
||||
`isRequest` BOOLEAN NOT NULL, -- true if member asked to join league, false if league invited member.
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
UNIQUE (`leagueId`, `memberId`),
|
||||
|
||||
FOREIGN KEY(`leagueId`) REFERENCES `league`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY(`memberId`) REFERENCES `member`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertInvitationTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertInvitationTrigger` BEFORE INSERT ON `invitation`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateInvitationTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateInvitationTrigger` BEFORE UPDATE ON `invitation`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
27
data/league.sql
Normal file
27
data/league.sql
Normal file
@@ -0,0 +1,27 @@
|
||||
CREATE TABLE IF NOT EXISTS `league` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`name` VARCHAR(64) NOT NULL UNIQUE,
|
||||
`public` BOOLEAN NOT NULL,
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertLeagueTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertLeagueTrigger` BEFORE INSERT ON `league`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateLeagueTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateLeagueTrigger` BEFORE UPDATE ON `league`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
35
data/leagueMember.sql
Normal file
35
data/leagueMember.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
CREATE TABLE IF NOT EXISTS `leagueMember` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`leagueId` BINARY(16) NOT NULL,
|
||||
`memberId` BINARY(16) NOT NULL,
|
||||
`nickName` VARCHAR(64),
|
||||
`roleId` BINARY(16) NOT NULL,
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
UNIQUE (`leagueId`, `memberId`),
|
||||
|
||||
FOREIGN KEY(`leagueId`) REFERENCES `league`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY(`memberId`) REFERENCES `member`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY(`roleId`) REFERENCES `role`(`id`)
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertLeagueMemberTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertLeagueMemberTrigger` BEFORE INSERT ON `leagueMember`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateLeagueMemberTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateLeagueMemberTrigger` BEFORE UPDATE ON `leagueMember`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
26
data/member.sql
Normal file
26
data/member.sql
Normal file
@@ -0,0 +1,26 @@
|
||||
CREATE TABLE IF NOT EXISTS `member` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`name` VARCHAR(64) NOT NULL,
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertMemberTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertMemberTrigger` BEFORE INSERT ON `member`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateMemberTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateMemberTrigger` BEFORE UPDATE ON `member`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
34
data/notification.sql
Normal file
34
data/notification.sql
Normal file
@@ -0,0 +1,34 @@
|
||||
CREATE TABLE IF NOT EXISTS `notification` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`templateId` BINARY(16) NOT NULL,
|
||||
`leagueMemberId` BINARY(16) NOT NULL,
|
||||
`referenceId` BINARY(16), -- used to link to injury, invitation, etc.
|
||||
`reference` VARCHAR(128), -- describe what the referenceId is referring to
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
UNIQUE (`templateId`, `leagueMemberId`, `referenceId`),
|
||||
|
||||
FOREIGN KEY(`templateId`) REFERENCES `notificationTemplate`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY(`leagueMemberId`) REFERENCES `leagueMember`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertNotificationTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertNotificationTrigger` BEFORE INSERT ON `notification`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateNotificationTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateNotificationTrigger` BEFORE UPDATE ON `notification`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
14
data/notificationTemplate.sql
Normal file
14
data/notificationTemplate.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
CREATE TABLE IF NOT EXISTS `notificationTemplate` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`code` VARCHAR(16) UNIQUE,
|
||||
`title` VARCHAR(256),
|
||||
`message` VARCHAR(2048)
|
||||
);
|
||||
|
||||
INSERT IGNORE INTO `notificationTemplate` (`id`, `code`, `title`, `message`) VALUES
|
||||
(UUID_TO_BIN(UUID()), 'YOUR-TURN', "It's your turn to pick!", "Why don't you go on ahead and make the next addition to your team?"), -- referenceId will be draftPick
|
||||
(UUID_TO_BIN(UUID()), 'INJURED-PLAYER', "Your player was injured.", "Unfortunately, one of your players has went and gotten himself injured."), -- referenceId will be injury
|
||||
(UUID_TO_BIN(UUID()), 'INACTIVE-PLAYER', "Your player is no longer available.", "Unfortunately, one of your players has retired, or was demoted, or something."), -- referenceId will be player
|
||||
(UUID_TO_BIN(UUID()), 'INACTIVE-PLAYER', "Your player is no longer available.", "Unfortunately, one of your players has retired, or was demoted, or something."), -- referenceId will be player
|
||||
(UUID_TO_BIN(UUID()), 'LEAGUE-REQUEST', "Someone wants to join your league.", "You probably shouldn't leave them hanging."), -- referenceId will be invitation
|
||||
(UUID_TO_BIN(UUID()), 'LEAGUE-INVITE', "Someone wants you to join their league.", "You probably shouldn't leave them hanging."); -- referenceId will be invitation
|
||||
39
data/player.sql
Normal file
39
data/player.sql
Normal file
@@ -0,0 +1,39 @@
|
||||
CREATE TABLE IF NOT EXISTS `player` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`sourceId` INT(11) UNIQUE, -- player's id on fantasybaseballnerd.com
|
||||
`name` VARCHAR(64) NOT NULL, -- this and below is data from fantasybaseballnerd.com
|
||||
`positionId` BINARY(16) NOT NULL,
|
||||
`team` VARCHAR(3),
|
||||
`bats` VARCHAR(1),
|
||||
`throws` VARCHAR(1),
|
||||
`height` VARCHAR(5),
|
||||
`weight` INT(3),
|
||||
`jersey` INT(2),
|
||||
`birthDate` DATE,
|
||||
|
||||
`active` BOOLEAN, -- when the player isn't returned by api anymore, set to true
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
FOREIGN KEY(`positionId`) REFERENCES `position`(`id`)
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertPlayerTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertPlayerTrigger` BEFORE INSERT ON `player`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updatePlayerTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updatePlayerTrigger` BEFORE UPDATE ON `player`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
21
data/position.sql
Normal file
21
data/position.sql
Normal file
@@ -0,0 +1,21 @@
|
||||
CREATE TABLE IF NOT EXISTS `position` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`code` VARCHAR(2) UNIQUE,
|
||||
`name` VARCHAR(64) NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
INSERT IGNORE INTO `position` (`id`, `code`, `name`) VALUES
|
||||
(UUID_TO_BIN(UUID()), 'DH', 'designated hitter'),
|
||||
(UUID_TO_BIN(UUID()), 'C', 'catcher'),
|
||||
(UUID_TO_BIN(UUID()), 'P', 'pitcher'),
|
||||
(UUID_TO_BIN(UUID()), 'RP', 'relief pitcher'),
|
||||
(UUID_TO_BIN(UUID()), 'SP', 'starting pitcher'),
|
||||
(UUID_TO_BIN(UUID()), 'IF', 'in field'),
|
||||
(UUID_TO_BIN(UUID()), '1B', 'first base'),
|
||||
(UUID_TO_BIN(UUID()), '2B', 'second base'),
|
||||
(UUID_TO_BIN(UUID()), 'SS', 'short stop'),
|
||||
(UUID_TO_BIN(UUID()), '3B', 'third base'),
|
||||
(UUID_TO_BIN(UUID()), 'OF', 'out field'),
|
||||
(UUID_TO_BIN(UUID()), 'LF', 'left field'),
|
||||
(UUID_TO_BIN(UUID()), 'RF', 'right field'),
|
||||
(UUID_TO_BIN(UUID()), 'CF', 'center field');
|
||||
11
data/role.sql
Normal file
11
data/role.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE IF NOT EXISTS `role` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`name` VARCHAR(64) NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
INSERT IGNORE INTO `role` (`id`, `name`) VALUES
|
||||
(UUID_TO_BIN(UUID()), 'owner'),
|
||||
(UUID_TO_BIN(UUID()), 'admin'),
|
||||
(UUID_TO_BIN(UUID()), 'advanced'), -- someone who can manage their own stuff but no one else's.
|
||||
(UUID_TO_BIN(UUID()), 'member'),
|
||||
(UUID_TO_BIN(UUID()), 'spectator');
|
||||
33
data/sso.sql
Normal file
33
data/sso.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
CREATE TABLE IF NOT EXISTS `sso` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`memberId` BINARY(16) NOT NULL,
|
||||
`token` VARCHAR(64) NOT NULL,
|
||||
`ssoTypeId` BINARY(16) NOT NULL,
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
UNIQUE (`token`, `ssoTypeId`),
|
||||
|
||||
FOREIGN KEY(`memberId`) REFERENCES `member`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY(`ssoTypeId`) REFERENCES `ssoType`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertSsoTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertSsoTrigger` BEFORE INSERT ON `sso`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateSsoTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateSsoTrigger` BEFORE UPDATE ON `sso`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
8
data/ssoType.sql
Normal file
8
data/ssoType.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS `ssoType` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`source` VARCHAR(32) UNIQUE
|
||||
);
|
||||
|
||||
INSERT IGNORE INTO `ssoType` (`id`, `source`) VALUES
|
||||
(UUID_TO_BIN(UUID()), 'Google'),
|
||||
(UUID_TO_BIN(UUID()), 'Facebook');
|
||||
40
data/statistic.sql
Normal file
40
data/statistic.sql
Normal file
@@ -0,0 +1,40 @@
|
||||
CREATE TABLE IF NOT EXISTS `statistic` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`playerId` BINARY(16) NOT NULL,
|
||||
`rank` INT(11), -- this and below are from fantasybaseballnerd.com
|
||||
`averageRank` REAL(3,3),
|
||||
`atBats` INT(11),
|
||||
`runs` INT(11),
|
||||
`homeRuns` INT(11),
|
||||
`runsBattedIn` INT(11),
|
||||
`stolenBases` INT(11),
|
||||
`battingAverage` REAL(3,3),
|
||||
`onBasePlusSlugging` REAL(3,3),
|
||||
`singles` INT(11),
|
||||
`doubles` INT(11),
|
||||
`triples` INT(11),
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
FOREIGN KEY(`playerId`) REFERENCES `player`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertStatisticTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertStatisticTrigger` BEFORE INSERT ON `statistic`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateStatisticTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateStatisticTrigger` BEFORE UPDATE ON `statistic`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
29
data/team.sql
Normal file
29
data/team.sql
Normal file
@@ -0,0 +1,29 @@
|
||||
CREATE TABLE IF NOT EXISTS `team` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`name` VARCHAR(64) NOT NULL,
|
||||
`leagueMemberId` BINARY(16) NOT NULL,
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
FOREIGN KEY(`leagueMemberId`) REFERENCES `leagueMember`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertTeamTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertTeamTrigger` BEFORE INSERT ON `team`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateTeamTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateTeamTrigger` BEFORE UPDATE ON `team`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
31
data/teamPlayer.sql
Normal file
31
data/teamPlayer.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
CREATE TABLE IF NOT EXISTS `teamPlayer` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`teamId` BINARY(16) NOT NULL,
|
||||
`playerId` BINARY(16) NOT NULL,
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
UNIQUE (`teamId`, `playerId`),
|
||||
FOREIGN KEY(`teamId`) REFERENCES `team`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY(`playerId`) REFERENCES `player`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertTeamPlayerTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertTeamPlayerTrigger` BEFORE INSERT ON `teamPlayer`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateTeamPlayerTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateTeamPlayerTrigger` BEFORE UPDATE ON `teamPlayer`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
32
data/trade.sql
Normal file
32
data/trade.sql
Normal file
@@ -0,0 +1,32 @@
|
||||
CREATE TABLE IF NOT EXISTS `trade` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`teamId` BINARY(16) NOT NULL,
|
||||
`oldPlayerId` BINARY(16) NOT NULL,
|
||||
`newPlayerId` BINARY(16) NOT NULL,
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
FOREIGN KEY(`teamId`) REFERENCES `team`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY(`oldPlayerId`) REFERENCES `player`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY(`newPlayerId`) REFERENCES `player`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertTradeTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertTradeTrigger` BEFORE INSERT ON `trade`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateTradeTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateTradeTrigger` BEFORE UPDATE ON `trade`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
31
data/user.sql
Normal file
31
data/user.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
CREATE TABLE IF NOT EXISTS `user` (
|
||||
`id` BINARY(16) PRIMARY KEY,
|
||||
`username` VARCHAR(254) NOT NULL UNIQUE,
|
||||
`password` BINARY(60),
|
||||
`memberId` BINARY(16) NOT NULL UNIQUE,
|
||||
`verified` TINYINT(1), -- 0 when they first create the account, 1 once they verify the email address
|
||||
|
||||
`created` DATETIME,
|
||||
`modified` DATETIME,
|
||||
|
||||
FOREIGN KEY(`memberId`) REFERENCES `member`(`id`) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TRIGGER IF EXISTS `insertUserTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `insertUserTrigger` BEFORE INSERT ON `user`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = IFNULL(NEW.`created`, NOW());
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
DROP TRIGGER IF EXISTS `updateUserTrigger`;
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `updateUserTrigger` BEFORE UPDATE ON `user`
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.`created` = OLD.`created`;
|
||||
SET NEW.`modified` = NOW();
|
||||
END$$
|
||||
DELIMITER ;
|
||||
20
docs/endpoints.txt
Normal file
20
docs/endpoints.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
account.create
|
||||
|
||||
league.create
|
||||
league.invite
|
||||
league.getMembers (incl role)
|
||||
|
||||
member.requestToJoin
|
||||
member.getLeagues
|
||||
|
||||
leagueMember.getTeam
|
||||
|
||||
draft.pick
|
||||
draft.getTurn
|
||||
|
||||
team.getPlayers (incl position, stats, injury)
|
||||
|
||||
notification.create
|
||||
|
||||
|
||||
start with creating an account and logging in.
|
||||
23
docs/notes.txt
Normal file
23
docs/notes.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Will have to deal with when a player is no longer returned by fantasybaseballnerd, but is in use in peoples teams.
|
||||
Some examples of when this would happen: a player retires, a player is demoted out of mlb.
|
||||
|
||||
Will have to deal with when a league owner deletes their account or league
|
||||
|
||||
what to do if any of the things are deleted that have a reference id in notification table
|
||||
|
||||
todo items (not a priority):
|
||||
player photos
|
||||
trading
|
||||
auto score keeping
|
||||
divisions (split league into different groups for places)
|
||||
|
||||
notifications that will exist:
|
||||
your turn to draft
|
||||
your player was injured
|
||||
someone wants to join your league
|
||||
someone invited you to join their league
|
||||
your player is inactive
|
||||
|
||||
automated processes:
|
||||
refreshing players and their stats, setting players inactive: notification
|
||||
populating injuries: notification
|
||||
12
docs/testing_setup.txt
Normal file
12
docs/testing_setup.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
How to Setup the Testing Environment on Localhost
|
||||
|
||||
run MySQL Installer and configure server
|
||||
go to last option and apply configuration. This will start the server.
|
||||
Run SQLyog and connect to the localhost.
|
||||
if object browser isnt showing up, hit Ctrl + B
|
||||
open mysql command line client and run `use baseball; source path\to\_MASTER_.sql`
|
||||
|
||||
|
||||
go get github.com/go-sql-driver/mysql
|
||||
go get github.com/gorilla/mux
|
||||
go get github.com/twinj/uuid
|
||||
Reference in New Issue
Block a user