112 lines
3.5 KiB
Go
112 lines
3.5 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
|
|
"git.loyso.art/frx/kurious/internal/common/config"
|
|
"git.loyso.art/frx/kurious/internal/common/xcontext"
|
|
"git.loyso.art/frx/kurious/internal/kurious/adapters"
|
|
"git.loyso.art/frx/kurious/internal/kurious/app"
|
|
"git.loyso.art/frx/kurious/internal/kurious/app/command"
|
|
"git.loyso.art/frx/kurious/internal/kurious/app/query"
|
|
"git.loyso.art/frx/kurious/internal/kurious/domain"
|
|
)
|
|
|
|
type RepositoryEngine uint8
|
|
|
|
const (
|
|
RepositoryEngineUnknown RepositoryEngine = iota
|
|
RepositoryEngineYDB
|
|
RepositoryEngineSqlite
|
|
)
|
|
|
|
type ApplicationConfig struct {
|
|
LogConfig config.Log
|
|
YDB config.YDB
|
|
Sqlite config.Sqlite
|
|
Engine RepositoryEngine
|
|
}
|
|
|
|
type Application struct {
|
|
app.Application
|
|
|
|
log *slog.Logger
|
|
closers []io.Closer
|
|
}
|
|
|
|
func NewApplication(ctx context.Context, cfg ApplicationConfig, mapper domain.CourseMapper) (out Application, err error) {
|
|
log := config.NewSLogger(cfg.LogConfig)
|
|
|
|
var repoCloser io.Closer
|
|
var courseadapter domain.CourseRepository
|
|
var organizationrepo domain.OrganizationRepository
|
|
switch cfg.Engine {
|
|
case RepositoryEngineSqlite:
|
|
sqliteConnection, err := adapters.NewSqliteConnection(ctx, cfg.Sqlite, log.With(slog.String("db", "sqlite")))
|
|
if err != nil {
|
|
return Application{}, fmt.Errorf("making sqlite connection: %w", err)
|
|
}
|
|
|
|
courseadapter = sqliteConnection.CourseRepository()
|
|
organizationrepo = sqliteConnection.Organization()
|
|
repoCloser = sqliteConnection
|
|
case RepositoryEngineYDB:
|
|
ydbConn, err := adapters.NewYDBConnection(ctx, cfg.YDB, log.With(slog.String("db", "ydb")))
|
|
if err != nil {
|
|
return Application{}, fmt.Errorf("making ydb connection: %w", err)
|
|
}
|
|
|
|
courseadapter = ydbConn.CourseRepository()
|
|
organizationrepo = ydbConn.Organization()
|
|
repoCloser = ydbConn
|
|
default:
|
|
return Application{}, errors.New("unable to decide which db engine to use")
|
|
}
|
|
|
|
err = mapper.CollectCounts(ctx, courseadapter)
|
|
if err != nil {
|
|
xcontext.LogWithWarnError(ctx, log, err, "unable to properly collect counts")
|
|
}
|
|
|
|
application := app.Application{
|
|
Commands: app.Commands{
|
|
InsertCourses: command.NewCreateCoursesHandler(courseadapter, log),
|
|
InsertCourse: command.NewCreateCourseHandler(courseadapter, log),
|
|
DeleteCourse: command.NewDeleteCourseHandler(courseadapter, log),
|
|
UpdateCourseDescription: command.NewUpdateCourseDescriptionHandler(courseadapter, log),
|
|
|
|
InsertOrganization: command.NewCreateOrganizationHandler(organizationrepo, log),
|
|
},
|
|
Queries: app.Queries{
|
|
ListCourses: query.NewListCourseHandler(courseadapter, mapper, log),
|
|
ListLearningTypes: query.NewListLearningTypesHandler(courseadapter, mapper, log),
|
|
ListCourseThematics: query.NewListCourseThematicsHandler(courseadapter, mapper, log),
|
|
ListCourseStatistics: query.NewListCoursesStatsHandler(mapper, courseadapter, log),
|
|
GetCourse: query.NewGetCourseHandler(courseadapter, mapper, log),
|
|
|
|
ListOrganzations: query.NewListOrganizationsHandler(organizationrepo, log),
|
|
ListOrganizationsStats: query.NewListOrganizationsStatsHandler(organizationrepo, log),
|
|
GetOrganization: query.NewGetOrganizationHandler(organizationrepo, log),
|
|
},
|
|
}
|
|
|
|
out = Application{Application: application}
|
|
out.closers = append(out.closers, repoCloser)
|
|
out.log = log
|
|
|
|
return out, nil
|
|
}
|
|
|
|
func (app Application) Close() {
|
|
for _, closer := range app.closers {
|
|
err := closer.Close()
|
|
if err != nil {
|
|
app.log.Error("unable to close closer", slog.Any("err", err))
|
|
}
|
|
}
|
|
}
|