refactor: migrate backend database
This commit is contained in:
96
backend/database/database.go
Normal file
96
backend/database/database.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
|
||||
"github.com/yyc12345/coconut-leaf/backend/config"
|
||||
)
|
||||
|
||||
// ResponseBody is the envelope returned by every Database operation, mirroring
|
||||
// the legacy database.ResponseBody. Data is any so each method can return its
|
||||
// own shape (scalar, []string, []any row, [][]any rows, ...). JSON tags keep the
|
||||
// legacy lowercase keys (success/error/data) used by ConstructResponseBody.
|
||||
type ResponseBody struct {
|
||||
Success bool `json:"success"`
|
||||
Error string `json:"error"`
|
||||
Data any `json:"data"`
|
||||
}
|
||||
|
||||
// CalendarUpdateOptions carries the optional fields of CalendarUpdate. A nil
|
||||
// pointer means "not provided", mirroring the legacy **optArgs semantics: a
|
||||
// field is applied only when its pointer is non-nil.
|
||||
type CalendarUpdateOptions struct {
|
||||
BelongTo *string
|
||||
Title *string
|
||||
Description *string
|
||||
EventDateTimeStart *int64
|
||||
EventDateTimeEnd *int64
|
||||
LoopRules *string
|
||||
TimezoneOffset *int64
|
||||
}
|
||||
|
||||
// AdminUpdateOptions carries the optional fields of AdminUpdate. A nil pointer
|
||||
// means "not provided".
|
||||
type AdminUpdateOptions struct {
|
||||
Password *string
|
||||
IsAdmin *bool
|
||||
}
|
||||
|
||||
// Deps bundles the shared dependencies a database implementation needs: the
|
||||
// loaded configuration and a logger. It is passed to database constructors and
|
||||
// stored inside each implementation so they can read config and emit logs.
|
||||
type Deps struct {
|
||||
Cfg *config.Config
|
||||
Logger *slog.Logger
|
||||
}
|
||||
|
||||
// Database describes every database operation the Gin server may use. It is the
|
||||
// Go equivalent of the legacy CalendarDatabase public surface: each method takes
|
||||
// a context.Context for cancellation and returns a ResponseBody whose
|
||||
// Success/Error fields encode failure (mirroring the legacy decorator behavior).
|
||||
type Database interface {
|
||||
Init(username, password string) error
|
||||
Close() error
|
||||
|
||||
CommonSalt(ctx context.Context, username string) ResponseBody
|
||||
CommonLogin(ctx context.Context, username, password, clientUa, clientIp string) ResponseBody
|
||||
CommonWebLogin(ctx context.Context, username, password, clientUa, clientIp string) ResponseBody
|
||||
CommonLogout(ctx context.Context, token string) ResponseBody
|
||||
CommonTokenValid(ctx context.Context, token string) ResponseBody
|
||||
|
||||
CalendarGetFull(ctx context.Context, token string, startDateTime, endDateTime int64) ResponseBody
|
||||
CalendarGetList(ctx context.Context, token string, startDateTime, endDateTime int64) ResponseBody
|
||||
CalendarGetDetail(ctx context.Context, token, uuid string) ResponseBody
|
||||
CalendarUpdate(ctx context.Context, token, uuid, lastChange string, opts CalendarUpdateOptions) ResponseBody
|
||||
CalendarAdd(ctx context.Context, token, belongTo, title, description string, eventDateTimeStart, eventDateTimeEnd int64, loopRules string, timezoneOffset int64) ResponseBody
|
||||
CalendarDelete(ctx context.Context, token, uuid, lastChange string) ResponseBody
|
||||
|
||||
CollectionGetFullOwn(ctx context.Context, token string) ResponseBody
|
||||
CollectionGetListOwn(ctx context.Context, token string) ResponseBody
|
||||
CollectionGetDetailOwn(ctx context.Context, token, uuid string) ResponseBody
|
||||
CollectionAddOwn(ctx context.Context, token, name string) ResponseBody
|
||||
CollectionUpdateOwn(ctx context.Context, token, uuid, name, lastChange string) ResponseBody
|
||||
CollectionDeleteOwn(ctx context.Context, token, uuid, lastChange string) ResponseBody
|
||||
CollectionGetSharing(ctx context.Context, token, uuid string) ResponseBody
|
||||
CollectionDeleteSharing(ctx context.Context, token, uuid, target, lastChange string) ResponseBody
|
||||
CollectionAddSharing(ctx context.Context, token, uuid, target, lastChange string) ResponseBody
|
||||
CollectionGetShared(ctx context.Context, token string) ResponseBody
|
||||
|
||||
TodoGetFull(ctx context.Context, token string) ResponseBody
|
||||
TodoGetList(ctx context.Context, token string) ResponseBody
|
||||
TodoGetDetail(ctx context.Context, token, uuid string) ResponseBody
|
||||
TodoAdd(ctx context.Context, token string) ResponseBody
|
||||
TodoUpdate(ctx context.Context, token, uuid, data, lastChange string) ResponseBody
|
||||
TodoDelete(ctx context.Context, token, uuid, lastChange string) ResponseBody
|
||||
|
||||
AdminGet(ctx context.Context, token string) ResponseBody
|
||||
AdminAdd(ctx context.Context, token, username string) ResponseBody
|
||||
AdminUpdate(ctx context.Context, token, username string, opts AdminUpdateOptions) ResponseBody
|
||||
AdminDelete(ctx context.Context, token, username string) ResponseBody
|
||||
|
||||
ProfileIsAdmin(ctx context.Context, token string) ResponseBody
|
||||
ProfileChangePassword(ctx context.Context, token, password string) ResponseBody
|
||||
ProfileGetToken(ctx context.Context, token string) ResponseBody
|
||||
ProfileDeleteToken(ctx context.Context, token, deleteToken string) ResponseBody
|
||||
}
|
||||
143
backend/database/mysql_database.go
Normal file
143
backend/database/mysql_database.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var errNotImplemented = errors.New("mysql database: not implemented")
|
||||
|
||||
var notImplResp = ResponseBody{Success: false, Error: errNotImplemented.Error()}
|
||||
|
||||
// stubDatabase provides a not-implemented default for every Database method.
|
||||
// MysqlDatabase embeds it so the interface is satisfied without hand-writing
|
||||
// each method; individual methods can be overridden on MysqlDatabase later.
|
||||
type stubDatabase struct{}
|
||||
|
||||
func (stubDatabase) Init(username, password string) error { return errNotImplemented }
|
||||
func (stubDatabase) Close() error { return errNotImplemented }
|
||||
|
||||
func (stubDatabase) CommonSalt(ctx context.Context, username string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CommonLogin(ctx context.Context, username, password, clientUa, clientIp string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CommonWebLogin(ctx context.Context, username, password, clientUa, clientIp string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CommonLogout(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CommonTokenValid(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
|
||||
func (stubDatabase) CalendarGetFull(ctx context.Context, token string, startDateTime, endDateTime int64) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CalendarGetList(ctx context.Context, token string, startDateTime, endDateTime int64) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CalendarGetDetail(ctx context.Context, token, uuid string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CalendarUpdate(ctx context.Context, token, uuid, lastChange string, opts CalendarUpdateOptions) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CalendarAdd(ctx context.Context, token, belongTo, title, description string, eventDateTimeStart, eventDateTimeEnd int64, loopRules string, timezoneOffset int64) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CalendarDelete(ctx context.Context, token, uuid, lastChange string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
|
||||
func (stubDatabase) CollectionGetFullOwn(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CollectionGetListOwn(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CollectionGetDetailOwn(ctx context.Context, token, uuid string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CollectionAddOwn(ctx context.Context, token, name string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CollectionUpdateOwn(ctx context.Context, token, uuid, name, lastChange string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CollectionDeleteOwn(ctx context.Context, token, uuid, lastChange string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CollectionGetSharing(ctx context.Context, token, uuid string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CollectionDeleteSharing(ctx context.Context, token, uuid, target, lastChange string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CollectionAddSharing(ctx context.Context, token, uuid, target, lastChange string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) CollectionGetShared(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
|
||||
func (stubDatabase) TodoGetFull(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) TodoGetList(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) TodoGetDetail(ctx context.Context, token, uuid string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) TodoAdd(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) TodoUpdate(ctx context.Context, token, uuid, data, lastChange string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) TodoDelete(ctx context.Context, token, uuid, lastChange string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
|
||||
func (stubDatabase) AdminGet(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) AdminAdd(ctx context.Context, token, username string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) AdminUpdate(ctx context.Context, token, username string, opts AdminUpdateOptions) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) AdminDelete(ctx context.Context, token, username string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
|
||||
func (stubDatabase) ProfileIsAdmin(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) ProfileChangePassword(ctx context.Context, token, password string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) ProfileGetToken(ctx context.Context, token string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
func (stubDatabase) ProfileDeleteToken(ctx context.Context, token, deleteToken string) ResponseBody {
|
||||
return notImplResp
|
||||
}
|
||||
|
||||
// MysqlDatabase implements Database as a fully not-implemented stub by
|
||||
// embedding stubDatabase. Real MySQL support can be filled in later by
|
||||
// overriding individual methods.
|
||||
type MysqlDatabase struct {
|
||||
stubDatabase
|
||||
deps Deps
|
||||
}
|
||||
|
||||
// NewMysqlDatabase returns a not-implemented MysqlDatabase. The deps are stored
|
||||
// for symmetry with NewSqlite3Database but not yet used.
|
||||
func NewMysqlDatabase(deps Deps) (*MysqlDatabase, error) {
|
||||
return &MysqlDatabase{deps: deps}, nil
|
||||
}
|
||||
1138
backend/database/sqlite_database.go
Normal file
1138
backend/database/sqlite_database.go
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user