You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
3.3 KiB
173 lines
3.3 KiB
package mysql
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"git.aiterp.net/stufflog3/stufflog3/models"
|
|
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore"
|
|
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/sqltypes"
|
|
"git.aiterp.net/stufflog3/stufflog3/usecases/items"
|
|
"git.aiterp.net/stufflog3/stufflog3/usecases/projects"
|
|
"git.aiterp.net/stufflog3/stufflog3/usecases/scopes"
|
|
"git.aiterp.net/stufflog3/stufflog3/usecases/sprints"
|
|
"git.aiterp.net/stufflog3/stufflog3/usecases/stats"
|
|
"github.com/Masterminds/squirrel"
|
|
"time"
|
|
|
|
_ "github.com/go-sql-driver/mysql"
|
|
)
|
|
|
|
type Database struct {
|
|
db *sql.DB
|
|
q *mysqlcore.Queries
|
|
}
|
|
|
|
func (db *Database) Scopes() scopes.Repository {
|
|
return &scopeRepository{
|
|
db: db.db,
|
|
q: db.q,
|
|
}
|
|
}
|
|
|
|
func (db *Database) Projects() projects.Repository {
|
|
return &projectRepository{
|
|
db: db.db,
|
|
q: db.q,
|
|
}
|
|
}
|
|
|
|
func (db *Database) Stats() stats.Repository {
|
|
return &statsRepository{
|
|
db: db.db,
|
|
q: db.q,
|
|
}
|
|
}
|
|
|
|
func (db *Database) Items() items.Repository {
|
|
return &itemRepository{
|
|
db: db.db,
|
|
q: db.q,
|
|
}
|
|
}
|
|
|
|
func (db *Database) Sprints() sprints.Repository {
|
|
return &sprintRepository{
|
|
db: db.db,
|
|
q: db.q,
|
|
}
|
|
}
|
|
|
|
func Connect(host string, port int, username, password, database string) (*Database, error) {
|
|
db, err := sql.Open("mysql", fmt.Sprintf(
|
|
"%s:%s@(%s:%d)/%s?parseTime=true", username, password, host, port, database,
|
|
))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
db.SetMaxOpenConns(10)
|
|
db.SetMaxIdleConns(10)
|
|
db.SetConnMaxIdleTime(time.Minute)
|
|
|
|
err = db.Ping()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
q := mysqlcore.New(db)
|
|
|
|
return &Database{db: db, q: q}, nil
|
|
}
|
|
|
|
func timePtr(nullTime sql.NullTime) *time.Time {
|
|
if nullTime.Valid {
|
|
return &nullTime.Time
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func intPtr(nullInt32 sql.NullInt32) *int {
|
|
if nullInt32.Valid {
|
|
v := int(nullInt32.Int32)
|
|
return &v
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func sqlTimePtr(ptr *time.Time) sql.NullTime {
|
|
if ptr != nil {
|
|
return sql.NullTime{Time: *ptr, Valid: true}
|
|
} else {
|
|
return sql.NullTime{Valid: false}
|
|
}
|
|
}
|
|
|
|
func sqlDatePtr(ptr *models.Date) sqltypes.NullDate {
|
|
if ptr != nil {
|
|
return sqltypes.NullDate{Date: *ptr, Valid: true}
|
|
} else {
|
|
return sqltypes.NullDate{Valid: false}
|
|
}
|
|
}
|
|
|
|
func sqlIntPtr(ptr *int) sql.NullInt32 {
|
|
if ptr != nil {
|
|
return sql.NullInt32{Int32: int32(*ptr), Valid: true}
|
|
} else {
|
|
return sql.NullInt32{Valid: false}
|
|
}
|
|
}
|
|
|
|
func sqlJsonPtr(ptr interface{}) sqltypes.NullRawMessage {
|
|
if ptr != nil {
|
|
j, err := json.Marshal(ptr)
|
|
|
|
return sqltypes.NullRawMessage{RawMessage: j, Valid: err == nil}
|
|
} else {
|
|
return sqltypes.NullRawMessage{Valid: false}
|
|
}
|
|
}
|
|
|
|
const (
|
|
tagObjectKindItem = iota
|
|
tagObjectKindRequirement
|
|
tagObjectKindProject
|
|
)
|
|
|
|
func fetchTags(ctx context.Context, db *sql.DB, kind int, ids []int, cb func(id int, tag string)) error {
|
|
query, args, err := squirrel.Select("object_id, tag_name").
|
|
From("tag").
|
|
Where(squirrel.Eq{"object_id": ids, "object_kind": kind}).
|
|
OrderBy("tag_name").
|
|
ToSql()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
rows, err := db.QueryContext(ctx, query, args...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for rows.Next() {
|
|
var tagStr string
|
|
var objectID int
|
|
err := rows.Scan(&objectID, &tagStr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cb(objectID, tagStr)
|
|
}
|
|
|
|
if err := rows.Close(); err != nil {
|
|
return err
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|