Skip to content

Commit 6f77f78

Browse files
Refactor database date formats (#810)
1 parent 0536723 commit 6f77f78

19 files changed

+270
-475
lines changed

gqlgen.yml

-8
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,6 @@ models:
2222
fields:
2323
url:
2424
resolver: true
25-
PerformerEdit:
26-
fields:
27-
birthdate:
28-
resolver: true
29-
SceneEdit:
30-
fields:
31-
date:
32-
resolver: true
3325
QueryPerformersResultType:
3426
model: github.com/stashapp/stash-box/pkg/models.PerformerQuery
3527
QueryEditsResultType:

pkg/api/performer_edit_integration_test.go

+2-8
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,13 @@ func (s *performerEditTestRunner) verifyPerformerEditDetails(input models.Perfor
8989
c := fieldComparator{r: &s.testRunner}
9090
c.strPtrStrPtr(input.Name, performerDetails.Name, "Name")
9191
c.strPtrStrPtr(input.Disambiguation, performerDetails.Disambiguation, "Disambiguation")
92+
c.strPtrStrPtr(input.Birthdate, performerDetails.Birthdate, "Birthdate")
9293

9394
assert.DeepEqual(s.t, input.Aliases, performerDetails.AddedAliases)
9495
assert.Assert(s.t, input.Gender.IsValid() && (input.Gender.String() == *performerDetails.Gender))
9596

9697
s.compareURLs(input.Urls, performerDetails.AddedUrls)
9798

98-
date, accuracy, _ := models.ParseFuzzyString(input.Birthdate)
99-
assert.Assert(s.t, accuracy.Valid && (accuracy.String == *performerDetails.BirthdateAccuracy))
100-
assert.Assert(s.t, date.Valid && (date.String == *performerDetails.Birthdate))
10199
assert.Assert(s.t, input.Ethnicity.IsValid() && (input.Ethnicity.String() == *performerDetails.Ethnicity))
102100
assert.Assert(s.t, input.Country != nil && (*input.Country == *performerDetails.Country))
103101
assert.Assert(s.t, input.EyeColor.IsValid() && (input.EyeColor.String() == *performerDetails.EyeColor))
@@ -142,14 +140,10 @@ func (s *performerEditTestRunner) verifyPerformerEdit(input models.PerformerEdit
142140
urls, _ := resolver.Urls(s.ctx, performer)
143141
s.compareURLs(input.Urls, urls)
144142

145-
date, accuracy, _ := models.ParseFuzzyString(input.Birthdate)
146-
147143
if input.Birthdate == nil {
148-
assert.Assert(s.t, !performer.BirthdateAccuracy.Valid)
149144
assert.Assert(s.t, !performer.Birthdate.Valid)
150145
} else {
151-
assert.Equal(s.t, accuracy.String, performer.BirthdateAccuracy.String)
152-
assert.Equal(s.t, date.String, performer.Birthdate.String)
146+
assert.Equal(s.t, *input.Birthdate, performer.Birthdate.String)
153147
}
154148

155149
if input.Ethnicity == nil {

pkg/api/performer_integration_test.go

+4-6
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,8 @@ func (s *performerTestRunner) verifyCreatedPerformer(input models.PerformerCreat
102102
urls, _ := s.resolver.Performer().Urls(s.ctx, performer)
103103
assert.Assert(s.t, compareUrls(input.Urls, urls), "Urls")
104104

105-
inputDate, inputAccuracy, _ := models.ParseFuzzyString(input.Birthdate)
106-
birthdate, _ := r.Birthdate(s.ctx, performer)
107-
assert.Assert(s.t, bothNil(birthdate, input.Birthdate) || (!oneNil(birthdate, input.Birthdate) && birthdate.Date == inputDate.String && birthdate.Accuracy.String() == inputAccuracy.String))
105+
birthdate, _ := r.BirthDate(s.ctx, performer)
106+
assert.DeepEqual(s.t, birthdate, input.Birthdate)
108107

109108
ethnicity, _ := r.Ethnicity(s.ctx, performer)
110109
assert.DeepEqual(s.t, ethnicity, input.Ethnicity)
@@ -263,9 +262,8 @@ func (s *performerTestRunner) verifyUpdatedPerformer(input models.PerformerUpdat
263262
urls, _ := s.resolver.Performer().Urls(s.ctx, performer)
264263
assert.Assert(s.t, compareUrls(input.Urls, urls))
265264

266-
inputDate, inputAccuracy, _ := models.ParseFuzzyString(input.Birthdate)
267-
birthdate, _ := r.Birthdate(s.ctx, performer)
268-
assert.Assert(s.t, birthdate == nil || (birthdate.Date == inputDate.String && birthdate.Accuracy.String() == inputAccuracy.String))
265+
birthdate, _ := s.resolver.Performer().BirthDate(s.ctx, performer)
266+
assert.DeepEqual(s.t, birthdate, input.Birthdate)
269267

270268
tattoos, _ := s.resolver.Performer().Tattoos(s.ctx, performer)
271269
assert.Assert(s.t, compareBodyMods(input.Tattoos, tattoos))

pkg/api/resolver_model_performer.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ func (r *performerResolver) Urls(ctx context.Context, obj *models.Performer) ([]
4646
return dataloader.For(ctx).PerformerUrlsByID.Load(obj.ID)
4747
}
4848

49+
// Deprecated: use `BirthDate`
4950
func (r *performerResolver) Birthdate(ctx context.Context, obj *models.Performer) (*models.FuzzyDate, error) {
50-
ret := obj.ResolveBirthdate()
51-
return &ret, nil
51+
return resolveFuzzyDate(obj.Birthdate), nil
5252
}
5353

5454
func (r *performerResolver) BirthDate(ctx context.Context, obj *models.Performer) (*string, error) {
55-
return resolveFuzzyDate(&obj.Birthdate.String, &obj.BirthdateAccuracy.String), nil
55+
return resolveNullString(obj.Birthdate), nil
5656
}
5757

5858
func (r *performerResolver) Age(ctx context.Context, obj *models.Performer) (*int, error) {

pkg/api/resolver_model_performer_edit.go

-4
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ func (r *performerEditResolver) RemovedImages(ctx context.Context, obj *models.P
6464
return imageList(ctx, obj.RemovedImages)
6565
}
6666

67-
func (r *performerEditResolver) Birthdate(ctx context.Context, obj *models.PerformerEdit) (*string, error) {
68-
return resolveFuzzyDate(obj.Birthdate, obj.BirthdateAccuracy), nil
69-
}
70-
7167
func (r *performerEditResolver) Images(ctx context.Context, obj *models.PerformerEdit) ([]*models.Image, error) {
7268
fac := r.getRepoFactory(ctx)
7369
id, err := fac.Edit().FindPerformerID(obj.EditID)

pkg/api/resolver_model_scene.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,17 @@ func (r *sceneResolver) Code(ctx context.Context, obj *models.Scene) (*string, e
3434
return resolveNullString(obj.Code), nil
3535
}
3636

37-
// Deprecated: use `DateFuzzy`
37+
// Deprecated: use `ReleaseDate`
3838
func (r *sceneResolver) Date(ctx context.Context, obj *models.Scene) (*string, error) {
39-
return &obj.ResolveDate().Date, nil
39+
ret := resolveFuzzyDate(obj.Date)
40+
if ret != nil {
41+
return &ret.Date, nil
42+
}
43+
return nil, nil
4044
}
4145

4246
func (r *sceneResolver) ReleaseDate(ctx context.Context, obj *models.Scene) (*string, error) {
43-
return resolveFuzzyDate(&obj.Date.String, &obj.DateAccuracy.String), nil
47+
return resolveNullString(obj.Date), nil
4448
}
4549

4650
func (r *sceneResolver) Studio(ctx context.Context, obj *models.Scene) (*models.Studio, error) {

pkg/api/resolver_model_scene_edit.go

-4
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,6 @@ func (r *sceneEditResolver) Fingerprints(ctx context.Context, obj *models.SceneE
133133
return ret, nil
134134
}
135135

136-
func (r *sceneEditResolver) Date(ctx context.Context, obj *models.SceneEdit) (*string, error) {
137-
return resolveFuzzyDate(obj.Date, obj.DateAccuracy), nil
138-
}
139-
140136
func (r *sceneEditResolver) Images(ctx context.Context, obj *models.SceneEdit) ([]*models.Image, error) {
141137
fac := r.getRepoFactory(ctx)
142138
id, err := fac.Edit().FindSceneID(obj.EditID)

pkg/api/scene_edit_integration_test.go

+2-17
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,7 @@ func (s *sceneEditTestRunner) verifySceneEditDetails(input models.SceneEditDetai
9494
c.strPtrStrPtr(input.Code, sceneDetails.Code, "Code")
9595
c.uuidPtrUUIDPtr(input.StudioID, sceneDetails.StudioID, "StudioID")
9696
c.intPtrInt64Ptr(input.Duration, sceneDetails.Duration, "Duration")
97-
98-
inputDate, inputAccuracy, _ := models.ParseFuzzyString(input.Date)
99-
assert.Assert(s.t, inputAccuracy.Valid && (inputAccuracy.String == *sceneDetails.DateAccuracy), "DateAccuracy mismatch")
100-
assert.Equal(s.t, inputDate.String, *sceneDetails.Date)
97+
c.strPtrStrPtr(input.Date, sceneDetails.Date, "Date")
10198

10299
s.compareURLs(input.Urls, sceneDetails.AddedUrls)
103100

@@ -119,19 +116,7 @@ func (s *sceneEditTestRunner) verifySceneEdit(input models.SceneEditDetailsInput
119116
c.strPtrNullStr(input.Code, scene.Code, "Code")
120117
c.uuidPtrNullUUID(input.StudioID, scene.StudioID, "StudioID")
121118
c.intPtrNullInt64(input.Duration, scene.Duration, "Duration")
122-
123-
inputDate, inputAccuracy, _ := models.ParseFuzzyString(input.Date)
124-
if input.Date == nil {
125-
assert.Assert(s.t, !scene.DateAccuracy.Valid)
126-
} else {
127-
assert.Equal(s.t, inputAccuracy.String, scene.DateAccuracy.String)
128-
}
129-
130-
if input.Date == nil {
131-
assert.Assert(s.t, !scene.Date.Valid)
132-
} else {
133-
assert.Equal(s.t, inputDate.String, scene.Date.String)
134-
}
119+
c.strPtrNullStr(input.Date, scene.Date, "Date")
135120

136121
urls, _ := resolver.Urls(s.ctx, scene)
137122
s.compareURLs(input.Urls, urls)

pkg/api/sql_resolver.go

+19-16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package api
22

33
import (
44
"database/sql"
5+
"fmt"
56

67
"github.com/stashapp/stash-box/pkg/models"
78
"github.com/stashapp/stash-box/pkg/utils"
@@ -31,25 +32,27 @@ func resolveNullInt64(value sql.NullInt64) (*int, error) {
3132
return nil, nil
3233
}
3334

34-
func resolveFuzzyDate(date *string, accuracy *string) *string {
35-
if date == nil || *date == "" {
35+
func resolveFuzzyDate(date sql.NullString) *models.FuzzyDate {
36+
if !date.Valid {
3637
return nil
3738
}
3839

39-
resolvedAccuracy := models.DateAccuracyEnumDay.String()
40-
if accuracy != nil && *accuracy != "" {
41-
resolvedAccuracy = *accuracy
42-
}
43-
44-
switch resolvedAccuracy {
45-
case models.DateAccuracyEnumDay.String():
46-
return date
47-
case models.DateAccuracyEnumMonth.String():
48-
ret := (*date)[0:7]
49-
return &ret
50-
case models.DateAccuracyEnumYear.String():
51-
ret := (*date)[0:4]
52-
return &ret
40+
switch {
41+
case len(date.String) == 4:
42+
return &models.FuzzyDate{
43+
Accuracy: models.DateAccuracyEnumYear,
44+
Date: fmt.Sprintf("%s-01-01", date.String),
45+
}
46+
case len(date.String) == 7:
47+
return &models.FuzzyDate{
48+
Accuracy: models.DateAccuracyEnumMonth,
49+
Date: fmt.Sprintf("%s-01", date.String),
50+
}
51+
case len(date.String) == 10:
52+
return &models.FuzzyDate{
53+
Accuracy: models.DateAccuracyEnumDay,
54+
Date: date.String,
55+
}
5356
}
5457

5558
return nil

pkg/database/database.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"github.com/jmoiron/sqlx"
55
)
66

7-
var appSchemaVersion uint = 41
7+
var appSchemaVersion uint = 42
88

99
var databaseProviders map[string]databaseProvider
1010

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
-- Transform scene date columns to single string column
2+
ALTER TABLE "scenes" RENAME COLUMN "date" TO "date_old";
3+
ALTER TABLE "scenes" ADD COLUMN "date" TEXT;
4+
5+
UPDATE "scenes" SET "date" = (
6+
CASE
7+
WHEN "date_accuracy" = 'DAY' THEN TO_CHAR("date_old", 'YYYY-MM-DD')
8+
WHEN "date_accuracy" = 'MONTH' THEN TO_CHAR("date_old", 'YYYY-MM')
9+
WHEN "date_accuracy" = 'YEAR' THEN TO_CHAR("date_old", 'YYYY')
10+
END
11+
);
12+
13+
ALTER TABLE "scenes" DROP COLUMN "date_old";
14+
ALTER TABLE "scenes" DROP COLUMN "date_accuracy";
15+
16+
-- Transform performers birthdate columns to single string column
17+
ALTER TABLE "performers" RENAME COLUMN "birthdate" TO "birthdate_old";
18+
ALTER TABLE "performers" ADD COLUMN "birthdate" TEXT;
19+
20+
UPDATE "performers" SET "birthdate" = (
21+
CASE
22+
WHEN "birthdate_accuracy" = 'DAY' THEN TO_CHAR("birthdate_old", 'YYYY-MM-DD')
23+
WHEN "birthdate_accuracy" = 'MONTH' THEN TO_CHAR("birthdate_old", 'YYYY-MM')
24+
WHEN "birthdate_accuracy" = 'YEAR' THEN TO_CHAR("birthdate_old", 'YYYY')
25+
END
26+
);
27+
28+
ALTER TABLE "performers" DROP COLUMN "birthdate_old";
29+
ALTER TABLE "performers" DROP COLUMN "birthdate_accuracy";

pkg/models/extension_edit_details.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (e PerformerEditDetailsInput) PerformerEditFromDiff(orig Performer, inputAr
6161
oldData.Gender, newData.Gender = ed.nullStringEnum(orig.Gender, e.Gender)
6262
}
6363
if e.Birthdate != nil || inputArgs.Field("birthdate").IsNull() {
64-
oldData.Birthdate, oldData.BirthdateAccuracy, newData.Birthdate, newData.BirthdateAccuracy = ed.fuzzyDate(orig.Birthdate, orig.BirthdateAccuracy, e.Birthdate)
64+
oldData.Birthdate, newData.Birthdate = ed.nullString(orig.Birthdate, e.Birthdate)
6565
}
6666
if e.Ethnicity != nil || inputArgs.Field("ethnicity").IsNull() {
6767
oldData.Ethnicity, newData.Ethnicity = ed.nullStringEnum(orig.Ethnicity, e.Ethnicity)
@@ -183,7 +183,7 @@ func (e SceneEditDetailsInput) SceneEditFromDiff(orig Scene, inputArgs utils.Arg
183183
oldData.Details, newData.Details = ed.nullString(orig.Details, e.Details)
184184
}
185185
if e.Date != nil || inputArgs.Field("date").IsNull() {
186-
oldData.Date, oldData.DateAccuracy, newData.Date, newData.DateAccuracy = ed.fuzzyDate(orig.Date, orig.DateAccuracy, e.Date)
186+
oldData.Date, newData.Date = ed.nullString(orig.Date, e.Date)
187187
}
188188
if e.StudioID != nil || inputArgs.Field("studio_id").IsNull() {
189189
oldData.StudioID, newData.StudioID = ed.nullUUID(orig.StudioID, e.StudioID)

0 commit comments

Comments
 (0)