Skip to content

Commit 0e29477

Browse files
porisiusVilsolFeyko
authored
SMR: API support for Dedicated Servers (#12)
* feat: add query for resolving mod version constraints * fix: correct sql grouping * chore: dependency version bumps * chore: sample config file * chore: increase linter timeout * chore: fix workflow linter argument * Combine SMR DS Dev with Staging/Tags * migrate to go 1.18.2 * SML platform link insert * starting Mod platform links * Mod/SML platform custom model addition * chore: merge compatibility * Fixes and completion of SML Links * progress: mod links * Validation: add .so files to scanning * Validation: add .so files to scanning * Split Combined Zip to Separate * Remove side, add index, cleanup testing logs * DeleteCombinedMod Cleans up combined mod upload, either after separating and succeeding or on error. * Fix: smllink * Fix: modlink * Fix: SeparateMod * Fix: Validations * fixes: mod_links and added routes * chore: lint fixes, and there was a lot of them... * optimization: seperatemod * cleanup logging * cleanup: SML Links * fix attempt: Mod Link to match SML Link * SML Links to SML Arch * Mod Links to Mod Arch / Key * ModLinks convert to asset * Fix: ModLinks Asset * DeleteModLink and filter pdb/debug on upload * Arch and preloads for getMods * chore: make linter happy... wrapchecks for errors * fix: platform name for Win64Server platform * Rename to archs and remove unused code * Remove VT Key * Merge validations dll/so * Link is dead, all hail Arch * Remove unnecessary log * Remove TODO Validation * Better error logging plus lint satisfaction with wrapcheck * Missed the memo, sorry Vilsol * Doc Comment for downloadModArch and downloadModVersionArch * Added context for log * Optimize SeparateMod * removed unneeded function * chore:lint * Move deleting uploaded file after everything checks out * fix: change where legacy link is gathered, save correct size/hash * fix: do not take logger from context * fix: non-nullable compatibility info * chore: upgrade to go 1.19 chore: fix linter errors * chore: bump gqlgen dep for pwetty playground Co-authored-by: Vilsol <me@vil.so> Co-authored-by: Feyko <feykook@gmail.com>
1 parent cf7fde1 commit 0e29477

34 files changed

+982
-47
lines changed

dataloader/loaders.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func Middleware() func(handlerFunc echo.HandlerFunc) echo.HandlerFunc {
109109

110110
var entities []postgres.Version
111111
reqCtx := c.Request().Context()
112-
postgres.DBCtx(reqCtx).Where("approved = ? AND denied = ? AND mod_id IN ?", true, false, fetchIds).Order("created_at desc").Find(&entities)
112+
postgres.DBCtx(reqCtx).Preload("Arch").Where("approved = ? AND denied = ? AND mod_id IN ?", true, false, fetchIds).Order("created_at desc").Find(&entities)
113113

114114
for _, entity := range entities {
115115
byID[entity.ModID] = append(byID[entity.ModID], entity)
@@ -145,7 +145,7 @@ func Middleware() func(handlerFunc echo.HandlerFunc) echo.HandlerFunc {
145145

146146
var entities []postgres.Version
147147
reqCtx := c.Request().Context()
148-
postgres.DBCtx(reqCtx).Select(
148+
postgres.DBCtx(reqCtx).Preload("Arch").Select(
149149
"id",
150150
"created_at",
151151
"updated_at",

db/postgres/mod.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func GetModByID(ctx context.Context, modID string) *Mod {
2626

2727
func GetModByIDNoCache(ctx context.Context, modID string) *Mod {
2828
var mod Mod
29-
DBCtx(ctx).Preload("Tags").Find(&mod, "id = ?", modID)
29+
DBCtx(ctx).Preload("Tags").Preload("Versions.Arch").Find(&mod, "id = ?", modID)
3030

3131
if mod.ID == "" {
3232
return nil
@@ -44,7 +44,7 @@ func GetModByReference(ctx context.Context, modReference string) *Mod {
4444
}
4545

4646
var mod Mod
47-
DBCtx(ctx).Preload("Tags").Find(&mod, "mod_reference = ?", modReference)
47+
DBCtx(ctx).Preload("Tags").Preload("Versions.Arch").Find(&mod, "mod_reference = ?", modReference)
4848

4949
if mod.ID == "" {
5050
return nil
@@ -213,7 +213,7 @@ func NewModQuery(ctx context.Context, filter *models.ModFilter, unapproved bool,
213213
}
214214

215215
query = query.Where("approved = ? AND denied = ?", !unapproved, false)
216-
query = query.Preload("Tags")
216+
query = query.Preload("Tags").Preload("Versions.Arch")
217217
if filter != nil {
218218
if filter.Search != nil && *filter.Search != "" {
219219
cleanSearch := strings.Replace(strings.TrimSpace(*filter.Search), " ", " & ", -1)

db/postgres/mod_archs.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package postgres
2+
3+
import (
4+
"context"
5+
"strings"
6+
7+
"github.com/patrickmn/go-cache"
8+
"github.com/satisfactorymodding/smr-api/models"
9+
"github.com/satisfactorymodding/smr-api/util"
10+
)
11+
12+
func CreateModArch(ctx context.Context, modArch *ModArch) (*ModArch, error) {
13+
modArch.ID = util.GenerateUniqueID()
14+
DBCtx(ctx).Create(&modArch)
15+
return modArch, nil
16+
}
17+
18+
func GetModArch(ctx context.Context, modArchID string) *ModArch {
19+
cacheKey := "GetModArch_" + modArchID
20+
21+
if modArch, ok := dbCache.Get(cacheKey); ok {
22+
return modArch.(*ModArch)
23+
}
24+
25+
var modArch ModArch
26+
DBCtx(ctx).Find(&modArch, "id = ?", modArchID)
27+
28+
if modArch.ID == "" {
29+
return nil
30+
}
31+
32+
dbCache.Set(cacheKey, modArch, cache.DefaultExpiration)
33+
34+
return &modArch
35+
}
36+
37+
func GetModArchs(ctx context.Context, filter *models.ModArchFilter) []ModArch {
38+
var modArchs []ModArch
39+
query := DBCtx(ctx)
40+
41+
if filter != nil {
42+
query = query.Limit(*filter.Limit).
43+
Offset(*filter.Offset).
44+
Order(string(*filter.OrderBy) + " " + string(*filter.Order))
45+
46+
if filter.Search != nil && *filter.Search != "" {
47+
query = query.Where("to_tsvector(name) @@ to_tsquery(?)", strings.Replace(*filter.Search, " ", " & ", -1))
48+
}
49+
}
50+
51+
query.Find(&modArchs)
52+
return modArchs
53+
}
54+
55+
func GetVersionModArchs(ctx context.Context, versionID string) []ModArch {
56+
var modArchs []ModArch
57+
query := DBCtx(ctx).Find(&modArchs, "mod_version_arch_id = ?", versionID)
58+
59+
query.Find(&modArchs)
60+
return modArchs
61+
}
62+
63+
func GetModArchByID(ctx context.Context, modArchID string) *ModArch {
64+
cacheKey := "GetModArch_" + modArchID
65+
66+
if modArch, ok := dbCache.Get(cacheKey); ok {
67+
return modArch.(*ModArch)
68+
}
69+
70+
var modArch ModArch
71+
DBCtx(ctx).Find(&modArch, "id = ?", modArchID)
72+
73+
if modArch.ID == "" {
74+
return nil
75+
}
76+
77+
dbCache.Set(cacheKey, modArch, cache.DefaultExpiration)
78+
79+
return &modArch
80+
}
81+
82+
func GetModArchsByID(ctx context.Context, modArchIds []string) []ModArch {
83+
var modArchs []ModArch
84+
85+
DBCtx(ctx).Find(&modArchs, "id in (?)", modArchIds)
86+
87+
if len(modArchIds) != len(modArchs) {
88+
return nil
89+
}
90+
91+
return modArchs
92+
}
93+
94+
func GetModArchByPlatform(ctx context.Context, versionID string, platform string) *ModArch {
95+
cacheKey := "GetModArch_" + versionID + "_" + platform
96+
if modplatform, ok := dbCache.Get(cacheKey); ok {
97+
return modplatform.(*ModArch)
98+
}
99+
100+
var modplatform ModArch
101+
DBCtx(ctx).First(&modplatform, "mod_version_arch_id = ? AND platform = ?", versionID, platform)
102+
103+
if modplatform.ModVersionArchID == "" {
104+
return nil
105+
}
106+
107+
dbCache.Set(cacheKey, &modplatform, cache.DefaultExpiration)
108+
109+
return &modplatform
110+
}
111+
112+
func GetModArchDownload(ctx context.Context, versionID string, platform string) string {
113+
var modPlatform ModArch
114+
DBCtx(ctx).First(&modPlatform, "mod_version_arch_id = ? AND platform = ?", versionID, platform)
115+
116+
if modPlatform.ModVersionArchID == "" {
117+
return ""
118+
}
119+
120+
return modPlatform.Key
121+
}

db/postgres/postgres.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import (
55
"fmt"
66
"time"
77

8-
"github.com/satisfactorymodding/smr-api/db/postgres/otel"
9-
108
"github.com/patrickmn/go-cache"
119
"github.com/rs/zerolog"
1210
"github.com/rs/zerolog/log"
11+
"github.com/satisfactorymodding/smr-api/db/postgres/otel"
1312
"github.com/spf13/viper"
1413
"gorm.io/driver/postgres"
1514
"gorm.io/gorm"

db/postgres/postgres_types.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import (
66
"gorm.io/gorm"
77
)
88

9+
type Tabler interface {
10+
TableName() string
11+
}
12+
913
type SMRDates struct {
1014
CreatedAt time.Time
1115
UpdatedAt time.Time
@@ -91,6 +95,7 @@ type Version struct {
9195
Approved bool `gorm:"default:false;not null"`
9296
Denied bool `gorm:"default:false;not null"`
9397
Hotness uint
98+
Arch []ModArch `gorm:"foreignKey:mod_version_arch_id;preload:true"`
9499
Metadata *string
95100
ModReference *string
96101
VersionMajor *int
@@ -128,6 +133,7 @@ type SMLVersion struct {
128133
Stability string `sql:"type:version_stability"`
129134
Date time.Time
130135
Link string
136+
Arch []SMLArch `gorm:"foreignKey:sml_version_arch_id;preload:true"`
131137
Changelog string
132138
BootstrapVersion *string
133139
}
@@ -187,3 +193,27 @@ type Compatibility struct {
187193
State string
188194
Note string
189195
}
196+
197+
type ModArch struct {
198+
ID string `gorm:"primary_key;type:varchar(16)"`
199+
ModVersionArchID string
200+
Platform string
201+
Key string
202+
Size int64
203+
Hash string
204+
}
205+
206+
func (ModArch) TableName() string {
207+
return "mod_archs"
208+
}
209+
210+
type SMLArch struct {
211+
ID string `gorm:"primary_key;type:varchar(14)"`
212+
SMLVersionArchID string
213+
Platform string
214+
Link string
215+
}
216+
217+
func (SMLArch) TableName() string {
218+
return "sml_archs"
219+
}

db/postgres/sml_archs.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package postgres
2+
3+
import (
4+
"context"
5+
"strings"
6+
7+
"github.com/patrickmn/go-cache"
8+
"github.com/satisfactorymodding/smr-api/models"
9+
"github.com/satisfactorymodding/smr-api/util"
10+
)
11+
12+
func CreateSMLArch(ctx context.Context, smlLink *SMLArch) (*SMLArch, error) {
13+
smlLink.ID = util.GenerateUniqueID()
14+
15+
DBCtx(ctx).Create(&smlLink)
16+
17+
return smlLink, nil
18+
}
19+
20+
func GetSMLArch(ctx context.Context, smlLinkID string) *SMLArch {
21+
cacheKey := "GetSMLArch_" + smlLinkID
22+
23+
if smlLink, ok := dbCache.Get(cacheKey); ok {
24+
return smlLink.(*SMLArch)
25+
}
26+
27+
var smlLink SMLArch
28+
DBCtx(ctx).Find(&smlLink, "id = ?", smlLinkID)
29+
30+
if smlLink.ID == "" {
31+
return nil
32+
}
33+
34+
dbCache.Set(cacheKey, smlLink, cache.DefaultExpiration)
35+
36+
return &smlLink
37+
}
38+
39+
func GetSMLArchs(ctx context.Context, filter *models.SMLArchFilter) []SMLArch {
40+
var smlLinks []SMLArch
41+
query := DBCtx(ctx)
42+
43+
if filter != nil {
44+
query = query.Limit(*filter.Limit).
45+
Offset(*filter.Offset).
46+
Order(string(*filter.OrderBy) + " " + string(*filter.Order))
47+
48+
if filter.Search != nil && *filter.Search != "" {
49+
query = query.Where("to_tsvector(name) @@ to_tsquery(?)", strings.Replace(*filter.Search, " ", " & ", -1))
50+
}
51+
}
52+
53+
query.Find(&smlLinks)
54+
return smlLinks
55+
}
56+
57+
func GetSMLArchByID(ctx context.Context, smlLinkID string) []SMLArch {
58+
var smlLinks []SMLArch
59+
60+
DBCtx(ctx).Find(&smlLinks, "id in ?", smlLinkID)
61+
62+
if len(smlLinks) != 0 {
63+
return nil
64+
}
65+
66+
return smlLinks
67+
}
68+
69+
func GetSMLArchsByID(ctx context.Context, smlLinkIds []string) []SMLArch {
70+
var smlLinks []SMLArch
71+
72+
DBCtx(ctx).Find(&smlLinks, "id in (?)", smlLinkIds)
73+
74+
if len(smlLinkIds) != len(smlLinks) {
75+
return nil
76+
}
77+
78+
return smlLinks
79+
}
80+
81+
func GetSMLArchDownload(ctx context.Context, smlVersionID string, platform string) string {
82+
var smlPlatform SMLArch
83+
DBCtx(ctx).First(&smlPlatform, "sml_version_arch_id = ? AND platform = ?", smlVersionID, platform)
84+
85+
if smlPlatform.SMLVersionArchID == "" {
86+
return ""
87+
}
88+
89+
return smlPlatform.Link
90+
}

db/postgres/sml_version.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,21 @@ func CreateSMLVersion(ctx context.Context, smlVersion *SMLVersion) (*SMLVersion,
1313

1414
DBCtx(ctx).Create(&smlVersion)
1515

16+
for _, link := range smlVersion.Arch {
17+
DBCtx(ctx).Create(&SMLArch{
18+
ID: util.GenerateUniqueID(),
19+
SMLVersionArchID: smlVersion.ID,
20+
Platform: link.Platform,
21+
Link: link.Link,
22+
})
23+
}
24+
1625
return smlVersion, nil
1726
}
1827

1928
func GetSMLVersionByID(ctx context.Context, smlVersionID string) *SMLVersion {
2029
var smlVersion SMLVersion
21-
DBCtx(ctx).Find(&smlVersion, "id = ?", smlVersionID)
30+
DBCtx(ctx).Preload("Arch").Find(&smlVersion, "id in (?)", smlVersionID)
2231

2332
if smlVersion.ID == "" {
2433
return nil
@@ -41,13 +50,14 @@ func GetSMLVersions(ctx context.Context, filter *models.SMLVersionFilter) []SMLV
4150
}
4251
}
4352

44-
query.Find(&smlVersions)
53+
query.Preload("Arch").Find(&smlVersions)
54+
4555
return smlVersions
4656
}
4757

4858
func GetSMLVersionsByID(ctx context.Context, smlVersionIds []string) []SMLVersion {
4959
var smlVersions []SMLVersion
50-
DBCtx(ctx).Find(&smlVersions, "id in (?)", smlVersionIds)
60+
DBCtx(ctx).Preload("Arch").Find(&smlVersions, "id in (?)", smlVersionIds)
5161

5262
if len(smlVersionIds) != len(smlVersions) {
5363
return nil
@@ -73,7 +83,7 @@ func GetSMLVersionCount(ctx context.Context, filter *models.SMLVersionFilter) in
7383
func GetSMLLatestVersions(ctx context.Context) *[]SMLVersion {
7484
var smlVersions []SMLVersion
7585

76-
DBCtx(ctx).Select("distinct on (stability) *").
86+
DBCtx(ctx).Preload("Arch").Select("distinct on (stability) *").
7787
Order("stability, created_at desc").
7888
Find(&smlVersions)
7989

0 commit comments

Comments
 (0)