feat: Add database object models and repositories for Activity, Company, Customer, Project, TimeEntry, and User with GORM integration
This commit is contained in:
parent
4dda83904a
commit
17cb4505be
@ -7,8 +7,10 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
swaggerFiles "github.com/swaggo/files"
|
swaggerFiles "github.com/swaggo/files"
|
||||||
ginSwagger "github.com/swaggo/gin-swagger"
|
ginSwagger "github.com/swaggo/gin-swagger"
|
||||||
|
|
||||||
_ "github.com/timetracker/backend/docs" // This line is important for swag to work
|
_ "github.com/timetracker/backend/docs" // This line is important for swag to work
|
||||||
|
"github.com/timetracker/backend/internal/infrastructure/persistence/db"
|
||||||
|
_ "gorm.io/driver/postgres"
|
||||||
|
// GORM IMPORTS MARKER
|
||||||
)
|
)
|
||||||
|
|
||||||
// @title Time Tracker API
|
// @title Time Tracker API
|
||||||
@ -28,6 +30,16 @@ func helloHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
db, _ := db.NewDatasourceContainer(db.DatabaseConfig{
|
||||||
|
Host: "localhost",
|
||||||
|
Port: 5432,
|
||||||
|
User: "timetracker",
|
||||||
|
Password: "timetracker",
|
||||||
|
DBName: "timetracker",
|
||||||
|
SSLMode: "disable",
|
||||||
|
})
|
||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
r.GET("/", helloHandler)
|
r.GET("/", helloHandler)
|
||||||
|
@ -11,6 +11,14 @@ require (
|
|||||||
gorm.io/gorm v1.25.12
|
gorm.io/gorm v1.25.12
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||||
|
github.com/jackc/pgx/v5 v5.5.5 // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||||
|
golang.org/x/sync v0.12.0 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
github.com/bytedance/sonic v1.13.1 // indirect
|
github.com/bytedance/sonic v1.13.1 // indirect
|
||||||
@ -47,4 +55,5 @@ require (
|
|||||||
golang.org/x/tools v0.31.0 // indirect
|
golang.org/x/tools v0.31.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.5 // indirect
|
google.golang.org/protobuf v1.36.5 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
gorm.io/driver/postgres v1.5.11
|
||||||
)
|
)
|
||||||
|
@ -40,6 +40,14 @@ github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PU
|
|||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
|
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||||
|
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
@ -150,6 +158,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
|
||||||
|
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||||
|
15
backend/internal/domain/persistence/activity_datasource.go
Normal file
15
backend/internal/domain/persistence/activity_datasource.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package persistence
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ActivityDatasource interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.Activity, error)
|
||||||
|
Create(ctx context.Context, activity *entities.Activity) error
|
||||||
|
Update(ctx context.Context, activity *entities.Activity) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
}
|
15
backend/internal/domain/persistence/company_datasource.go
Normal file
15
backend/internal/domain/persistence/company_datasource.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package persistence
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CompanyDatasource interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.Company, error)
|
||||||
|
Create(ctx context.Context, company *entities.Company) error
|
||||||
|
Update(ctx context.Context, company *entities.Company) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
}
|
15
backend/internal/domain/persistence/customer_datasource.go
Normal file
15
backend/internal/domain/persistence/customer_datasource.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package persistence
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CustomerDatasource interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.Customer, error)
|
||||||
|
Create(ctx context.Context, customer *entities.Customer) error
|
||||||
|
Update(ctx context.Context, customer *entities.Customer) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
}
|
15
backend/internal/domain/persistence/project_datasource.go
Normal file
15
backend/internal/domain/persistence/project_datasource.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package persistence
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProjectDatasource interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.Project, error)
|
||||||
|
Create(ctx context.Context, project *entities.Project) error
|
||||||
|
Update(ctx context.Context, project *entities.Project) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
}
|
18
backend/internal/domain/persistence/timeentry_datasource.go
Normal file
18
backend/internal/domain/persistence/timeentry_datasource.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package persistence
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TimeEntryDatasource interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.TimeEntry, error)
|
||||||
|
Create(ctx context.Context, timeEntry *entities.TimeEntry) error
|
||||||
|
Update(ctx context.Context, timeEntry *entities.TimeEntry) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
GetByRange(ctx context.Context, userID ulid.ULID, from time.Time, to time.Time) ([]*entities.TimeEntry, error)
|
||||||
|
}
|
16
backend/internal/domain/persistence/user_datasource.go
Normal file
16
backend/internal/domain/persistence/user_datasource.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package persistence
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserDatasource interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.User, error)
|
||||||
|
Create(ctx context.Context, user *entities.User) error
|
||||||
|
Update(ctx context.Context, user *entities.User) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
GetByUsername(ctx context.Context, username string) (*entities.User, error)
|
||||||
|
}
|
15
backend/internal/domain/repositories/activity_repository.go
Normal file
15
backend/internal/domain/repositories/activity_repository.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ActivityRepository interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.Activity, error)
|
||||||
|
Create(ctx context.Context, activity *entities.Activity) error
|
||||||
|
Update(ctx context.Context, activity *entities.Activity) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
}
|
15
backend/internal/domain/repositories/company_repository.go
Normal file
15
backend/internal/domain/repositories/company_repository.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CompanyRepository interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.Company, error)
|
||||||
|
Create(ctx context.Context, company *entities.Company) error
|
||||||
|
Update(ctx context.Context, company *entities.Company) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
}
|
15
backend/internal/domain/repositories/customer_repository.go
Normal file
15
backend/internal/domain/repositories/customer_repository.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CustomerRepository interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.Customer, error)
|
||||||
|
Create(ctx context.Context, customer *entities.Customer) error
|
||||||
|
Update(ctx context.Context, customer *entities.Customer) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
}
|
15
backend/internal/domain/repositories/project_repository.go
Normal file
15
backend/internal/domain/repositories/project_repository.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProjectRepository interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.Project, error)
|
||||||
|
Create(ctx context.Context, project *entities.Project) error
|
||||||
|
Update(ctx context.Context, project *entities.Project) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
}
|
18
backend/internal/domain/repositories/timeentry_repository.go
Normal file
18
backend/internal/domain/repositories/timeentry_repository.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TimeEntryRepository interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.TimeEntry, error)
|
||||||
|
Create(ctx context.Context, timeEntry *entities.TimeEntry) error
|
||||||
|
Update(ctx context.Context, timeEntry *entities.TimeEntry) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
GetByRange(ctx context.Context, userID ulid.ULID, from time.Time, to time.Time) ([]*entities.TimeEntry, error)
|
||||||
|
}
|
16
backend/internal/domain/repositories/user_repository.go
Normal file
16
backend/internal/domain/repositories/user_repository.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserRepository interface {
|
||||||
|
Get(ctx context.Context, id ulid.ULID) (*entities.User, error)
|
||||||
|
Create(ctx context.Context, user *entities.User) error
|
||||||
|
Update(ctx context.Context, user *entities.User) error
|
||||||
|
Delete(ctx context.Context, id ulid.ULID) error
|
||||||
|
GetByUsername(ctx context.Context, username string) (*entities.User, error)
|
||||||
|
}
|
99
backend/internal/infrastructure/persistence/db/database.go
Normal file
99
backend/internal/infrastructure/persistence/db/database.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/timetracker/backend/internal/domain/repositories"
|
||||||
|
"github.com/timetracker/backend/internal/infrastructure/persistence/db/ds"
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DatabaseConfig enthält die Konfigurationsinformationen für die Datenbankverbindung
|
||||||
|
type DatabaseConfig struct {
|
||||||
|
Host string
|
||||||
|
Port int
|
||||||
|
User string
|
||||||
|
Password string
|
||||||
|
DBName string
|
||||||
|
SSLMode string
|
||||||
|
}
|
||||||
|
|
||||||
|
// DatasourceContainer enthält alle Repository-Instanzen
|
||||||
|
type DatasourceContainer struct {
|
||||||
|
ActivityDatasource repositories.ActivityRepository
|
||||||
|
CompanyDatasource repositories.CompanyRepository
|
||||||
|
CustomerDatasource repositories.CustomerRepository
|
||||||
|
ProjectDatasource repositories.ProjectRepository
|
||||||
|
TimeEntryDatasource repositories.TimeEntryRepository
|
||||||
|
UserDatasource repositories.UserRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDatasourceContainer erstellt und initialisiert alle Repository-Instanzen
|
||||||
|
func NewDatasourceContainer(config DatabaseConfig) (*DatasourceContainer, error) {
|
||||||
|
// Erstelle DSN (Data Source Name) für die Datenbankverbindung
|
||||||
|
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
|
||||||
|
config.Host, config.Port, config.User, config.Password, config.DBName, config.SSLMode)
|
||||||
|
|
||||||
|
// Erstelle SQL-Datenbankverbindung
|
||||||
|
sqlDB, err := sql.Open("pgx", dsn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("fehler beim Öffnen der SQL-Verbindung: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Konfiguriere Verbindungspool
|
||||||
|
sqlDB.SetMaxIdleConns(10)
|
||||||
|
sqlDB.SetMaxOpenConns(100)
|
||||||
|
|
||||||
|
// Initialisiere GORM mit der SQL-Verbindung
|
||||||
|
gormDB, err := gorm.Open(postgres.New(postgres.Config{
|
||||||
|
Conn: sqlDB,
|
||||||
|
}), &gorm.Config{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("fehler beim Initialisieren von GORM: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erstelle alle Repository-Instanzen
|
||||||
|
return &DatasourceContainer{
|
||||||
|
ActivityDatasource: ds.NewActivityDatasource(gormDB),
|
||||||
|
CompanyDatasource: ds.NewCompanyDatasource(gormDB),
|
||||||
|
CustomerDatasource: ds.NewCustomerDatasource(gormDB),
|
||||||
|
ProjectDatasource: ds.NewProjectDatasource(gormDB),
|
||||||
|
TimeEntryDatasource: ds.NewTimeEntryDatasource(gormDB),
|
||||||
|
UserDatasource: ds.NewUserDatasource(gormDB),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close schließt die Datenbankverbindung
|
||||||
|
func (r *DatasourceContainer) Close() error {
|
||||||
|
db, err := r.getGormDB()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlDB, err := db.DB()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sqlDB.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper-Methode, um die GORM-DB aus einem der Repositories zu extrahieren
|
||||||
|
func (r *DatasourceContainer) getGormDB() (*gorm.DB, error) {
|
||||||
|
// Wir nehmen an, dass alle Repositories das gleiche DB-Handle verwenden
|
||||||
|
// Deshalb können wir einfach eines der Repositories nehmen
|
||||||
|
// Dies funktioniert nur, wenn wir Zugriff auf die interne DB haben oder eine Methode hinzufügen
|
||||||
|
// Hier müsste angepasst werden, wie Sie Zugriff auf die GORM-DB bekommen
|
||||||
|
|
||||||
|
// Beispiel (müsste angepasst werden):
|
||||||
|
// activityDS, ok := r.ActivityRepository.(*ds.ActivityDatasource)
|
||||||
|
// if !ok {
|
||||||
|
// return nil, fmt.Errorf("Konnte GORM-DB nicht aus ActivityRepository extrahieren")
|
||||||
|
// }
|
||||||
|
// return activityDS.GetDB(), nil
|
||||||
|
|
||||||
|
// Placeholder für die tatsächliche Implementierung:
|
||||||
|
return nil, fmt.Errorf("getGormDB() muss implementiert werden")
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package ds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
"github.com/timetracker/backend/internal/domain/persistence"
|
||||||
|
"github.com/timetracker/backend/internal/infrastructure/persistence/db/dbo"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ActivityDatasource struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewActivityDatasource(db *gorm.DB) persistence.ActivityDatasource {
|
||||||
|
return &ActivityDatasource{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ActivityDatasource) Get(ctx context.Context, id ulid.ULID) (*entities.Activity, error) {
|
||||||
|
var activityDBO dbo.ActivityDBO
|
||||||
|
if err := r.db.WithContext(ctx).First(&activityDBO, "id = ?", id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
activity := &entities.Activity{
|
||||||
|
EntityBase: entities.EntityBase{
|
||||||
|
ID: activityDBO.ID,
|
||||||
|
CreatedAt: activityDBO.CreatedAt,
|
||||||
|
UpdatedAt: activityDBO.UpdatedAt,
|
||||||
|
},
|
||||||
|
Name: activityDBO.Name,
|
||||||
|
BillingRate: activityDBO.BillingRate,
|
||||||
|
}
|
||||||
|
|
||||||
|
return activity, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ActivityDatasource) Create(ctx context.Context, activity *entities.Activity) error {
|
||||||
|
activityDBO := dbo.ActivityDBO{
|
||||||
|
ID: activity.ID,
|
||||||
|
CreatedAt: activity.CreatedAt,
|
||||||
|
UpdatedAt: activity.UpdatedAt,
|
||||||
|
Name: activity.Name,
|
||||||
|
BillingRate: activity.BillingRate,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Create(&activityDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ActivityDatasource) Update(ctx context.Context, activity *entities.Activity) error {
|
||||||
|
activityDBO := dbo.ActivityDBO{
|
||||||
|
ID: activity.ID,
|
||||||
|
CreatedAt: activity.CreatedAt,
|
||||||
|
UpdatedAt: activity.UpdatedAt,
|
||||||
|
Name: activity.Name,
|
||||||
|
BillingRate: activity.BillingRate,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Save(&activityDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ActivityDatasource) Delete(ctx context.Context, id ulid.ULID) error {
|
||||||
|
return r.db.WithContext(ctx).Delete(&dbo.ActivityDBO{}, "id = ?", id).Error
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package ds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
"github.com/timetracker/backend/internal/domain/persistence"
|
||||||
|
"github.com/timetracker/backend/internal/infrastructure/persistence/db/dbo"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CompanyyDatasource struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCompanyDatasource(db *gorm.DB) persistence.CompanyDatasource {
|
||||||
|
return &CompanyyDatasource{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CompanyyDatasource) Get(ctx context.Context, id ulid.ULID) (*entities.Company, error) {
|
||||||
|
var companyDBO dbo.CompanyDBO
|
||||||
|
if err := r.db.WithContext(ctx).First(&companyDBO, "id = ?", id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
company := &entities.Company{
|
||||||
|
EntityBase: entities.EntityBase{
|
||||||
|
ID: companyDBO.ID,
|
||||||
|
CreatedAt: companyDBO.CreatedAt,
|
||||||
|
UpdatedAt: companyDBO.UpdatedAt,
|
||||||
|
},
|
||||||
|
Name: companyDBO.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
return company, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CompanyyDatasource) Create(ctx context.Context, company *entities.Company) error {
|
||||||
|
companyDBO := dbo.CompanyDBO{
|
||||||
|
ID: company.ID,
|
||||||
|
CreatedAt: company.CreatedAt,
|
||||||
|
UpdatedAt: company.UpdatedAt,
|
||||||
|
Name: company.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Create(&companyDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CompanyyDatasource) Update(ctx context.Context, company *entities.Company) error {
|
||||||
|
companyDBO := dbo.CompanyDBO{
|
||||||
|
ID: company.ID,
|
||||||
|
CreatedAt: company.CreatedAt,
|
||||||
|
UpdatedAt: company.UpdatedAt,
|
||||||
|
Name: company.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Save(&companyDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CompanyyDatasource) Delete(ctx context.Context, id ulid.ULID) error {
|
||||||
|
return r.db.WithContext(ctx).Delete(&dbo.CompanyDBO{}, "id = ?", id).Error
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package ds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
"github.com/timetracker/backend/internal/domain/persistence"
|
||||||
|
"github.com/timetracker/backend/internal/infrastructure/persistence/db/dbo"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CustomerDatasource struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCustomerDatasource(db *gorm.DB) persistence.CustomerDatasource {
|
||||||
|
return &CustomerDatasource{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CustomerDatasource) Get(ctx context.Context, id ulid.ULID) (*entities.Customer, error) {
|
||||||
|
var customerDBO dbo.CustomerDBO
|
||||||
|
if err := r.db.WithContext(ctx).First(&customerDBO, "id = ?", id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
customer := &entities.Customer{
|
||||||
|
EntityBase: entities.EntityBase{
|
||||||
|
ID: customerDBO.ID,
|
||||||
|
CreatedAt: customerDBO.CreatedAt,
|
||||||
|
UpdatedAt: customerDBO.UpdatedAt,
|
||||||
|
},
|
||||||
|
Name: customerDBO.Name,
|
||||||
|
CompanyID: customerDBO.CompanyID,
|
||||||
|
}
|
||||||
|
|
||||||
|
return customer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CustomerDatasource) Create(ctx context.Context, customer *entities.Customer) error {
|
||||||
|
customerDBO := dbo.CustomerDBO{
|
||||||
|
ID: customer.ID,
|
||||||
|
CreatedAt: customer.CreatedAt,
|
||||||
|
UpdatedAt: customer.UpdatedAt,
|
||||||
|
Name: customer.Name,
|
||||||
|
CompanyID: customer.CompanyID,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Create(&customerDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CustomerDatasource) Update(ctx context.Context, customer *entities.Customer) error {
|
||||||
|
customerDBO := dbo.CustomerDBO{
|
||||||
|
ID: customer.ID,
|
||||||
|
CreatedAt: customer.CreatedAt,
|
||||||
|
UpdatedAt: customer.UpdatedAt,
|
||||||
|
Name: customer.Name,
|
||||||
|
CompanyID: customer.CompanyID,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Save(&customerDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CustomerDatasource) Delete(ctx context.Context, id ulid.ULID) error {
|
||||||
|
return r.db.WithContext(ctx).Delete(&dbo.CustomerDBO{}, "id = ?", id).Error
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package ds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
"github.com/timetracker/backend/internal/domain/persistence"
|
||||||
|
"github.com/timetracker/backend/internal/infrastructure/persistence/db/dbo"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProjectDatasource struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProjectDatasource(db *gorm.DB) persistence.ProjectDatasource {
|
||||||
|
return &ProjectDatasource{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ProjectDatasource) Get(ctx context.Context, id ulid.ULID) (*entities.Project, error) {
|
||||||
|
var projectDBO dbo.ProjectDBO
|
||||||
|
if err := r.db.WithContext(ctx).First(&projectDBO, "id = ?", id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
project := &entities.Project{
|
||||||
|
EntityBase: entities.EntityBase{
|
||||||
|
ID: projectDBO.ID,
|
||||||
|
CreatedAt: projectDBO.CreatedAt,
|
||||||
|
UpdatedAt: projectDBO.UpdatedAt,
|
||||||
|
},
|
||||||
|
Name: projectDBO.Name,
|
||||||
|
CustomerID: projectDBO.CustomerID,
|
||||||
|
}
|
||||||
|
|
||||||
|
return project, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ProjectDatasource) Create(ctx context.Context, project *entities.Project) error {
|
||||||
|
projectDBO := dbo.ProjectDBO{
|
||||||
|
ID: project.ID,
|
||||||
|
CreatedAt: project.CreatedAt,
|
||||||
|
UpdatedAt: project.UpdatedAt,
|
||||||
|
Name: project.Name,
|
||||||
|
CustomerID: project.CustomerID,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Create(&projectDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ProjectDatasource) Update(ctx context.Context, project *entities.Project) error {
|
||||||
|
projectDBO := dbo.ProjectDBO{
|
||||||
|
ID: project.ID,
|
||||||
|
CreatedAt: project.CreatedAt,
|
||||||
|
UpdatedAt: project.UpdatedAt,
|
||||||
|
Name: project.Name,
|
||||||
|
CustomerID: project.CustomerID,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Save(&projectDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ProjectDatasource) Delete(ctx context.Context, id ulid.ULID) error {
|
||||||
|
return r.db.WithContext(ctx).Delete(&dbo.ProjectDBO{}, "id = ?", id).Error
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
package ds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
"github.com/timetracker/backend/internal/domain/persistence"
|
||||||
|
"github.com/timetracker/backend/internal/infrastructure/persistence/db/dbo"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TimeEntryDatasource struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTimeEntryDatasource(db *gorm.DB) persistence.TimeEntryDatasource {
|
||||||
|
return &TimeEntryDatasource{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *TimeEntryDatasource) Get(ctx context.Context, id ulid.ULID) (*entities.TimeEntry, error) {
|
||||||
|
var timeEntryDBO dbo.TimeEntryDBO
|
||||||
|
if err := r.db.WithContext(ctx).First(&timeEntryDBO, "id = ?", id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
timeEntry := &entities.TimeEntry{
|
||||||
|
EntityBase: entities.EntityBase{
|
||||||
|
ID: timeEntryDBO.ID,
|
||||||
|
CreatedAt: timeEntryDBO.CreatedAt,
|
||||||
|
UpdatedAt: timeEntryDBO.UpdatedAt,
|
||||||
|
},
|
||||||
|
UserID: timeEntryDBO.UserID,
|
||||||
|
ProjectID: timeEntryDBO.ProjectID,
|
||||||
|
ActivityID: timeEntryDBO.ActivityID,
|
||||||
|
Start: timeEntryDBO.Start,
|
||||||
|
End: timeEntryDBO.End,
|
||||||
|
Description: timeEntryDBO.Description,
|
||||||
|
Billable: timeEntryDBO.Billable,
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeEntry, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *TimeEntryDatasource) Create(ctx context.Context, timeEntry *entities.TimeEntry) error {
|
||||||
|
timeEntryDBO := dbo.TimeEntryDBO{
|
||||||
|
ID: timeEntry.ID,
|
||||||
|
CreatedAt: timeEntry.CreatedAt,
|
||||||
|
UpdatedAt: timeEntry.UpdatedAt,
|
||||||
|
UserID: timeEntry.UserID,
|
||||||
|
ProjectID: timeEntry.ProjectID,
|
||||||
|
ActivityID: timeEntry.ActivityID,
|
||||||
|
Start: timeEntry.Start,
|
||||||
|
End: timeEntry.End,
|
||||||
|
Description: timeEntry.Description,
|
||||||
|
Billable: timeEntry.Billable,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Create(&timeEntryDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *TimeEntryDatasource) Update(ctx context.Context, timeEntry *entities.TimeEntry) error {
|
||||||
|
timeEntryDBO := dbo.TimeEntryDBO{
|
||||||
|
ID: timeEntry.ID,
|
||||||
|
CreatedAt: timeEntry.CreatedAt,
|
||||||
|
UpdatedAt: timeEntry.UpdatedAt,
|
||||||
|
UserID: timeEntry.UserID,
|
||||||
|
ProjectID: timeEntry.ProjectID,
|
||||||
|
ActivityID: timeEntry.ActivityID,
|
||||||
|
Start: timeEntry.Start,
|
||||||
|
End: timeEntry.End,
|
||||||
|
Description: timeEntry.Description,
|
||||||
|
Billable: timeEntry.Billable,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Save(&timeEntryDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *TimeEntryDatasource) Delete(ctx context.Context, id ulid.ULID) error {
|
||||||
|
return r.db.WithContext(ctx).Delete(&dbo.TimeEntryDBO{}, "id = ?", id).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *TimeEntryDatasource) GetByRange(ctx context.Context, userID ulid.ULID, from time.Time, to time.Time) ([]*entities.TimeEntry, error) {
|
||||||
|
var timeEntryDBOs []*dbo.TimeEntryDBO
|
||||||
|
if err := r.db.WithContext(ctx).Where("user_id = ? AND start_time >= ? AND end_time <= ?", userID, from, to).Find(&timeEntryDBOs).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
timeEntries := make([]*entities.TimeEntry, len(timeEntryDBOs))
|
||||||
|
for i, timeEntryDBO := range timeEntryDBOs {
|
||||||
|
timeEntries[i] = &entities.TimeEntry{
|
||||||
|
EntityBase: entities.EntityBase{
|
||||||
|
ID: timeEntryDBO.ID,
|
||||||
|
CreatedAt: timeEntryDBO.CreatedAt,
|
||||||
|
UpdatedAt: timeEntryDBO.UpdatedAt,
|
||||||
|
},
|
||||||
|
UserID: timeEntryDBO.UserID,
|
||||||
|
ProjectID: timeEntryDBO.ProjectID,
|
||||||
|
ActivityID: timeEntryDBO.ActivityID,
|
||||||
|
Start: timeEntryDBO.Start,
|
||||||
|
End: timeEntryDBO.End,
|
||||||
|
Description: timeEntryDBO.Description,
|
||||||
|
Billable: timeEntryDBO.Billable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeEntries, nil
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package ds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"github.com/timetracker/backend/internal/domain/entities"
|
||||||
|
"github.com/timetracker/backend/internal/domain/persistence"
|
||||||
|
"github.com/timetracker/backend/internal/infrastructure/persistence/db/dbo"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserDatasource struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserDatasource(db *gorm.DB) persistence.UserDatasource {
|
||||||
|
return &UserDatasource{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserDatasource) Get(ctx context.Context, id ulid.ULID) (*entities.User, error) {
|
||||||
|
var userDBO dbo.UserDBO
|
||||||
|
if err := r.db.WithContext(ctx).First(&userDBO, "id = ?", id).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
user := &entities.User{
|
||||||
|
EntityBase: entities.EntityBase{
|
||||||
|
ID: userDBO.ID,
|
||||||
|
CreatedAt: userDBO.CreatedAt,
|
||||||
|
UpdatedAt: userDBO.UpdatedAt,
|
||||||
|
},
|
||||||
|
Username: userDBO.Username,
|
||||||
|
Password: userDBO.Password,
|
||||||
|
Role: userDBO.Role,
|
||||||
|
CompanyID: userDBO.CompanyID,
|
||||||
|
HourlyRate: userDBO.HourlyRate,
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserDatasource) Create(ctx context.Context, user *entities.User) error {
|
||||||
|
userDBO := dbo.UserDBO{
|
||||||
|
ID: user.ID,
|
||||||
|
CreatedAt: user.CreatedAt,
|
||||||
|
UpdatedAt: user.UpdatedAt,
|
||||||
|
Username: user.Username,
|
||||||
|
Password: user.Password,
|
||||||
|
Role: user.Role,
|
||||||
|
CompanyID: user.CompanyID,
|
||||||
|
HourlyRate: user.HourlyRate,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Create(&userDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserDatasource) Update(ctx context.Context, user *entities.User) error {
|
||||||
|
userDBO := dbo.UserDBO{
|
||||||
|
ID: user.ID,
|
||||||
|
CreatedAt: user.CreatedAt,
|
||||||
|
UpdatedAt: user.UpdatedAt,
|
||||||
|
Username: user.Username,
|
||||||
|
Password: user.Password,
|
||||||
|
Role: user.Role,
|
||||||
|
CompanyID: user.CompanyID,
|
||||||
|
HourlyRate: user.HourlyRate,
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.db.WithContext(ctx).Save(&userDBO).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserDatasource) Delete(ctx context.Context, id ulid.ULID) error {
|
||||||
|
return r.db.WithContext(ctx).Delete(&dbo.UserDBO{}, "id = ?", id).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserDatasource) GetByUsername(ctx context.Context, username string) (*entities.User, error) {
|
||||||
|
var userDBO dbo.UserDBO
|
||||||
|
if err := r.db.WithContext(ctx).Where("username = ?", username).First(&userDBO).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
user := &entities.User{
|
||||||
|
EntityBase: entities.EntityBase{
|
||||||
|
ID: userDBO.ID,
|
||||||
|
CreatedAt: userDBO.CreatedAt,
|
||||||
|
UpdatedAt: userDBO.UpdatedAt,
|
||||||
|
},
|
||||||
|
Username: userDBO.Username,
|
||||||
|
Password: userDBO.Password,
|
||||||
|
Role: userDBO.Role,
|
||||||
|
CompanyID: userDBO.CompanyID,
|
||||||
|
HourlyRate: userDBO.HourlyRate,
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user