Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(#40): add database skeleton and entities #46

Merged
merged 1 commit into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/openapi-spec/openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
openapi: 3.1.0
openapi: 3.0.4
info:
title: Room Service
description: |-
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ require (
github.com/stretchr/testify v1.8.4
github.com/urfave/cli/v2 v2.25.7
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/mysql v1.5.1
gorm.io/gorm v1.25.4
)

require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand Down
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
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/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
Expand Down Expand Up @@ -46,3 +52,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw=
gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
2 changes: 1 addition & 1 deletion internal/controller/controller.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package controller

import "github.com/eurofurence/reg-room-service/internal/database"
import "github.com/eurofurence/reg-room-service/internal/repository/database"

// Controller is the service interface, which defines
// the functions in the service layer of this application
Expand Down
3 changes: 0 additions & 3 deletions internal/database/repository.go

This file was deleted.

10 changes: 10 additions & 0 deletions internal/entity/base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package entity

import "time"

type Base struct {
ID string `gorm:"primaryKey; type:varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;NOT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
32 changes: 32 additions & 0 deletions internal/entity/group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package entity

// Group is a group of attendees that wish to be assigned to a Room together.
type Group struct {
Base

// Name is the name of the group
Name string `gorm:"type:varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;NOT NULL;uniqueIndex:room_group_name_uidx"`

// Flags is a comma-separated list of flags, with both leading and trailing comma. The allowed flags are configuration dependent
Flags string `gorm:"type:varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"`

// Comments are optional, not processed in any way
Comments string `gorm:"type:varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" testdiff:"ignore"`

// MaximumSize defaults to a value from service configuration, but we store it here so admins can increase it manually for some groups
MaximumSize uint

// Owner is the badge number (attendee ID) of the attendee owning the group. Ownership can be passed to another attendee.
Owner uint
}

// GroupMember associates attendees to a group, either as a member or as an invited member.
type GroupMember struct {
Member

// GroupID references the group to which the member belongs (or has been invited)
GroupID string `gorm:"type:varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;NOT NULL;index:room_group_member_grpid"`

// IsInvite is true if the member has been invited, or false if the member has already joined
IsInvite bool
}
18 changes: 18 additions & 0 deletions internal/entity/member.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package entity

import "gorm.io/gorm"

type Member struct {
// This contains ID = the badge number of the attendee (an attendee can only either be in a
// group or invited, and can only ever be in one room at the same time.
gorm.Model

// Nickname caches the nickname of the attendee
Nickname string `gorm:"type:varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;NOT NULL"`

// AvatarURL caches the url to obtain the avatar for this attendee, points to an image such as a png or jpg
AvatarURL string `gorm:"type:varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"`

// Flags is a comma-separated list of flags such as "has_key", with a leading and trailing comma
Flags string `gorm:"type:varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"`
}
24 changes: 24 additions & 0 deletions internal/entity/room.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package entity

type Room struct {
Base

// Name is the name of the room
Name string `gorm:"type:varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;NOT NULL;uniqueIndex:room_room_name_uidx"`

// Flags is a comma-separated list of flags, with both leading and trailing comma. The allowed flags are configuration dependent
Flags string `gorm:"type:varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"`

// Comments are optional, not processed in any way
Comments string `gorm:"type:varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci" testdiff:"ignore"`

// Size is the size of the room
Size uint
}

type RoomMember struct {
Member

// RoomID references the room to which the attendee belongs
RoomID string `gorm:"type:varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;NOT NULL;index:room_room_member_roomid"`
}
1 change: 1 addition & 0 deletions internal/repository/database/dbrepo/constructors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dbrepo
9 changes: 9 additions & 0 deletions internal/repository/database/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package database

import "context"

type Repository interface {
Open(ctx context.Context) error
Close(ctx context.Context)
Migrate(ctx context.Context) error
}
73 changes: 73 additions & 0 deletions internal/repository/database/mysqldb/implementation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package mysqldb

import (
"context"
aulogging "github.com/StephanHCB/go-autumn-logging"
"github.com/eurofurence/reg-room-service/internal/entity"
"github.com/eurofurence/reg-room-service/internal/repository/database"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"time"
)

type MysqlRepository struct {
db *gorm.DB
connectString string
Now func() time.Time
}

func Create(connectString string) database.Repository {
return &MysqlRepository{
Now: time.Now,
connectString: connectString,
}
}

func (r *MysqlRepository) Open(ctx context.Context) error {
gormConfig := gorm.Config{
NamingStrategy: schema.NamingStrategy{
TablePrefix: "room_",
},
Logger: logger.Default.LogMode(logger.Silent),
}

db, err := gorm.Open(mysql.Open(r.connectString), &gormConfig)
if err != nil {
aulogging.ErrorErrf(ctx, err, "failed to open mysql connection: %s", err.Error())
return err
}

sqlDb, err := db.DB()
if err != nil {
aulogging.ErrorErrf(ctx, err, "failed to configure mysql connection: %s", err.Error())
return err
}

// see https://making.pusher.com/production-ready-connection-pooling-in-go/
sqlDb.SetMaxOpenConns(100)
sqlDb.SetMaxIdleConns(50)
sqlDb.SetConnMaxLifetime(time.Minute * 10)

r.db = db
return nil
}

func (r *MysqlRepository) Close(_ context.Context) {
// no more db close in gorm v2
}

func (r *MysqlRepository) Migrate(ctx context.Context) error {
err := r.db.AutoMigrate(
&entity.Group{},
&entity.GroupMember{},
&entity.Room{},
&entity.RoomMember{},
)
if err != nil {
aulogging.Logger.NoCtx().Error().WithErr(err).Printf("failed to migrate mysql db: %s", err.Error())
return err
}
return nil
}
Loading