Use typed IDs instead of plain strings

This commit is contained in:
Eduard Urbach 2019-11-18 14:01:13 +09:00
parent e7c7e84334
commit a50a119e08
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
26 changed files with 75 additions and 44 deletions

View File

@ -17,9 +17,9 @@ import (
type AMV struct { type AMV struct {
File string `json:"file" editable:"true" type:"upload" filetype:"video" endpoint:"/api/upload/amv/:id/file"` File string `json:"file" editable:"true" type:"upload" filetype:"video" endpoint:"/api/upload/amv/:id/file"`
Title AMVTitle `json:"title" editable:"true"` Title AMVTitle `json:"title" editable:"true"`
MainAnimeID string `json:"mainAnimeId" editable:"true"` MainAnimeID AnimeID `json:"mainAnimeId" editable:"true"`
ExtraAnimeIDs []string `json:"extraAnimeIds" editable:"true"` ExtraAnimeIDs []AnimeID `json:"extraAnimeIds" editable:"true"`
VideoEditorIDs []string `json:"videoEditorIds" editable:"true"` VideoEditorIDs []UserID `json:"videoEditorIds" editable:"true"`
Links []Link `json:"links" editable:"true"` Links []Link `json:"links" editable:"true"`
Tags []string `json:"tags" editable:"true"` Tags []string `json:"tags" editable:"true"`
Info video.Info `json:"info"` Info video.Info `json:"info"`

View File

@ -12,7 +12,7 @@ import (
type Activity interface { type Activity interface {
Creator() *User Creator() *User
TypeName() string TypeName() string
GetID() string GetID() ID
GetCreated() string GetCreated() string
GetCreatedBy() UserID GetCreatedBy() UserID
GetCreatedTime() time.Time GetCreatedTime() time.Time

View File

@ -5,7 +5,7 @@ import "github.com/aerogo/nano"
// ActivityCreate is a user activity that creates something. // ActivityCreate is a user activity that creates something.
type ActivityCreate struct { type ActivityCreate struct {
ObjectType string `json:"objectType"` ObjectType string `json:"objectType"`
ObjectID string `json:"objectId"` ObjectID ID `json:"objectId"`
hasID hasID
hasCreator hasCreator

View File

@ -4,7 +4,7 @@ import "github.com/aerogo/nano"
// Analytics stores user-related statistics. // Analytics stores user-related statistics.
type Analytics struct { type Analytics struct {
UserID string `json:"userId" primary:"true"` UserID UserID `json:"userId" primary:"true"`
General GeneralAnalytics `json:"general"` General GeneralAnalytics `json:"general"`
Screen ScreenAnalytics `json:"screen"` Screen ScreenAnalytics `json:"screen"`
System SystemAnalytics `json:"system"` System SystemAnalytics `json:"system"`

View File

@ -71,7 +71,7 @@ func init() {
} }
// AnimeID represents an anime ID. // AnimeID represents an anime ID.
type AnimeID = string type AnimeID = ID
// Anime represents an anime. // Anime represents an anime.
type Anime struct { type Anime struct {
@ -102,15 +102,12 @@ type Anime struct {
hasDraft hasDraft
// Company IDs // Company IDs
StudioIDs []string `json:"studios" editable:"true"` StudioIDs []CompanyID `json:"studios" editable:"true"`
ProducerIDs []string `json:"producers" editable:"true"` ProducerIDs []CompanyID `json:"producers" editable:"true"`
LicensorIDs []string `json:"licensors" editable:"true"` LicensorIDs []CompanyID `json:"licensors" editable:"true"`
// Links to external websites // Links to external websites
Links []*Link `json:"links" editable:"true"` Links []*Link `json:"links" editable:"true"`
// SynopsisSource string `json:"synopsisSource" editable:"true"`
// Hashtag string `json:"hashtag"`
} }
// NewAnime creates a new anime. // NewAnime creates a new anime.

View File

@ -8,11 +8,14 @@ import (
"github.com/aerogo/nano" "github.com/aerogo/nano"
) )
// CharacterID represents a character ID.
type CharacterID = ID
// Character represents an anime or manga character. // Character represents an anime or manga character.
type Character struct { type Character struct {
Name CharacterName `json:"name" editable:"true"` Name CharacterName `json:"name" editable:"true"`
Image Image `json:"image"` Image Image `json:"image"`
MainQuoteID string `json:"mainQuoteId" editable:"true"` MainQuoteID QuoteID `json:"mainQuoteId" editable:"true"`
Description string `json:"description" editable:"true" type:"textarea"` Description string `json:"description" editable:"true" type:"textarea"`
Spoilers []Spoiler `json:"spoilers" editable:"true"` Spoilers []Spoiler `json:"spoilers" editable:"true"`
Attributes []*CharacterAttribute `json:"attributes" editable:"true"` Attributes []*CharacterAttribute `json:"attributes" editable:"true"`

View File

@ -6,6 +6,9 @@ import (
"github.com/aerogo/nano" "github.com/aerogo/nano"
) )
// CompanyID represents a company ID.
type CompanyID = ID
// Company represents an anime studio, producer or licensor. // Company represents an anime studio, producer or licensor.
type Company struct { type Company struct {
Name CompanyName `json:"name" editable:"true"` Name CompanyName `json:"name" editable:"true"`

View File

@ -9,21 +9,24 @@ import (
// EditLogEntry is an entry in the editor log. // EditLogEntry is an entry in the editor log.
type EditLogEntry struct { type EditLogEntry struct {
ID string `json:"id" primary:"true"` UserID UserID `json:"userId"`
UserID string `json:"userId"`
Action string `json:"action"` Action string `json:"action"`
ObjectID ID `json:"objectId"` // The ID of what was edited
ObjectType string `json:"objectType"` // The typename of what was edited ObjectType string `json:"objectType"` // The typename of what was edited
ObjectID string `json:"objectId"` // The ID of what was edited
Key string `json:"key"` Key string `json:"key"`
OldValue string `json:"oldValue"` OldValue string `json:"oldValue"`
NewValue string `json:"newValue"` NewValue string `json:"newValue"`
Created string `json:"created"` Created string `json:"created"`
hasID
} }
// NewEditLogEntry ... // NewEditLogEntry creates a new edit log entry.
func NewEditLogEntry(userID, action, objectType, objectID, key, oldValue, newValue string) *EditLogEntry { func NewEditLogEntry(userID UserID, action string, objectType string, objectID ID, key string, oldValue string, newValue string) *EditLogEntry {
return &EditLogEntry{ return &EditLogEntry{
ID: GenerateID("EditLogEntry"), hasID: hasID{
ID: GenerateID("EditLogEntry"),
},
UserID: userID, UserID: userID,
Action: action, Action: action,
ObjectType: objectType, ObjectType: objectType,

View File

@ -7,14 +7,18 @@ import (
"github.com/animenotifier/notify.moe/arn/validate" "github.com/animenotifier/notify.moe/arn/validate"
) )
// EpisodeID represents an episode ID.
type EpisodeID = ID
// Episode represents a single episode for an anime. // Episode represents a single episode for an anime.
type Episode struct { type Episode struct {
ID string `json:"id" primary:"true"`
AnimeID AnimeID `json:"animeId"` AnimeID AnimeID `json:"animeId"`
Number int `json:"number" editable:"true"` Number int `json:"number" editable:"true"`
Title EpisodeTitle `json:"title" editable:"true"` Title EpisodeTitle `json:"title" editable:"true"`
AiringDate AiringDate `json:"airingDate" editable:"true"` AiringDate AiringDate `json:"airingDate" editable:"true"`
Links map[string]string `json:"links"` Links map[string]string `json:"links"`
hasID
} }
// EpisodeTitle contains the title information for an anime episode. // EpisodeTitle contains the title information for an anime episode.
@ -27,7 +31,9 @@ type EpisodeTitle struct {
// NewAnimeEpisode creates a new anime episode. // NewAnimeEpisode creates a new anime episode.
func NewAnimeEpisode() *Episode { func NewAnimeEpisode() *Episode {
return &Episode{ return &Episode{
ID: GenerateID("Episode"), hasID: hasID{
ID: GenerateID("Episode"),
},
Number: -1, Number: -1,
} }
} }

View File

@ -11,6 +11,9 @@ import (
"github.com/akyoto/color" "github.com/akyoto/color"
) )
// GroupID represents a group ID.
type GroupID = ID
// Group represents a group of users. // Group represents a group of users.
type Group struct { type Group struct {
Name string `json:"name" editable:"true"` Name string `json:"name" editable:"true"`
@ -21,7 +24,7 @@ type Group struct {
Restricted bool `json:"restricted" editable:"true" tooltip:"Restricted groups can only be joined with the founder's permission."` Restricted bool `json:"restricted" editable:"true" tooltip:"Restricted groups can only be joined with the founder's permission."`
Tags []string `json:"tags" editable:"true"` Tags []string `json:"tags" editable:"true"`
Members []*GroupMember `json:"members"` Members []*GroupMember `json:"members"`
Neighbors []string `json:"neighbors"` Neighbors []GroupID `json:"neighbors"`
// Applications []UserApplication `json:"applications"` // Applications []UserApplication `json:"applications"`
// Mixins // Mixins

View File

@ -3,7 +3,7 @@ package arn
// HasEditor includes user ID and date for the last edit of this object. // HasEditor includes user ID and date for the last edit of this object.
type hasEditor struct { type hasEditor struct {
Edited string `json:"edited"` Edited string `json:"edited"`
EditedBy string `json:"editedBy"` EditedBy UserID `json:"editedBy"`
} }
// Editor returns the user who last edited this object. // Editor returns the user who last edited this object.

View File

@ -2,10 +2,10 @@ package arn
// hasID includes an object ID. // hasID includes an object ID.
type hasID struct { type hasID struct {
ID string `json:"id" primary:"true"` ID ID `json:"id" primary:"true"`
} }
// GetID returns the ID. // GetID returns the ID.
func (obj *hasID) GetID() string { func (obj *hasID) GetID() ID {
return obj.ID return obj.ID
} }

View File

@ -2,7 +2,7 @@ package arn
// HasLikes implements common like and unlike methods. // HasLikes implements common like and unlike methods.
type hasLikes struct { type hasLikes struct {
Likes []string `json:"likes"` Likes []UserID `json:"likes"`
} }
// Like makes the given user ID like the object. // Like makes the given user ID like the object.

View File

@ -6,7 +6,7 @@ import (
// HasPosts includes a list of Post IDs. // HasPosts includes a list of Post IDs.
type hasPosts struct { type hasPosts struct {
PostIDs []string `json:"posts"` PostIDs []PostID `json:"posts"`
} }
// AddPost adds a post to the object. // AddPost adds a post to the object.

4
arn/ID.go Normal file
View File

@ -0,0 +1,4 @@
package arn
// ID is used for object identification and is simply a string.
type ID = string

View File

@ -9,7 +9,7 @@ import (
// Notification represents a user-associated notification. // Notification represents a user-associated notification.
type Notification struct { type Notification struct {
UserID string `json:"userId"` UserID UserID `json:"userId"`
Created string `json:"created"` Created string `json:"created"`
Seen string `json:"seen"` Seen string `json:"seen"`

View File

@ -8,7 +8,7 @@ import (
// PayPalPayment is an approved and exeucted PayPal payment. // PayPalPayment is an approved and exeucted PayPal payment.
type PayPalPayment struct { type PayPalPayment struct {
UserID string `json:"userId"` UserID UserID `json:"userId"`
PayerID string `json:"payerId"` PayerID string `json:"payerId"`
Amount string `json:"amount"` Amount string `json:"amount"`
Currency string `json:"currency"` Currency string `json:"currency"`

View File

@ -10,10 +10,13 @@ import (
"github.com/aerogo/nano" "github.com/aerogo/nano"
) )
// PostID represents a post ID.
type PostID = ID
// Post is a comment related to any parent type in the database. // Post is a comment related to any parent type in the database.
type Post struct { type Post struct {
Tags []string `json:"tags" editable:"true"` Tags []string `json:"tags" editable:"true"`
ParentID string `json:"parentId" editable:"true"` ParentID ID `json:"parentId" editable:"true"`
ParentType string `json:"parentType"` ParentType string `json:"parentType"`
Edited string `json:"edited"` Edited string `json:"edited"`

View File

@ -19,10 +19,10 @@ type Postable interface {
// Use Get prefix for these to avoid a // Use Get prefix for these to avoid a
// name clash with the internal fields. // name clash with the internal fields.
GetID() string GetID() ID
GetText() string GetText() string
GetCreated() string GetCreated() string
GetParentID() string GetParentID() ID
GetParentType() string GetParentType() string
} }

View File

@ -4,8 +4,8 @@ import "github.com/aerogo/nano"
// Purchase represents an item purchase by a user. // Purchase represents an item purchase by a user.
type Purchase struct { type Purchase struct {
UserID string `json:"userId"` UserID UserID `json:"userId"`
ItemID string `json:"itemId"` ItemID ID `json:"itemId"`
Quantity int `json:"quantity"` Quantity int `json:"quantity"`
Price int `json:"price"` Price int `json:"price"`
Currency string `json:"currency"` Currency string `json:"currency"`

View File

@ -10,13 +10,16 @@ import (
"github.com/akyoto/color" "github.com/akyoto/color"
) )
// QuoteID represents a quote ID.
type QuoteID = ID
// Quote is a quote made by a character in an anime. // Quote is a quote made by a character in an anime.
type Quote struct { type Quote struct {
Text QuoteText `json:"text" editable:"true"` Text QuoteText `json:"text" editable:"true"`
CharacterID string `json:"characterId" editable:"true"` CharacterID CharacterID `json:"characterId" editable:"true"`
AnimeID AnimeID `json:"animeId" editable:"true"` AnimeID AnimeID `json:"animeId" editable:"true"`
EpisodeNumber int `json:"episode" editable:"true"` EpisodeNumber int `json:"episode" editable:"true"`
Time int `json:"time" editable:"true"` Time int `json:"time" editable:"true"`
hasID hasID
hasPosts hasPosts

View File

@ -1,4 +1,7 @@
package arn package arn
// SessionID represents a session ID.
type SessionID = ID
// Session stores session-related data. // Session stores session-related data.
type Session map[string]interface{} type Session map[SessionID]interface{}

View File

@ -29,7 +29,7 @@ const (
// Settings represents user settings. // Settings represents user settings.
type Settings struct { type Settings struct {
UserID string `json:"userId" primary:"true"` UserID UserID `json:"userId" primary:"true"`
SortBy string `json:"sortBy" editable:"true"` SortBy string `json:"sortBy" editable:"true"`
TitleLanguage string `json:"titleLanguage" editable:"true"` TitleLanguage string `json:"titleLanguage" editable:"true"`
Providers ServiceProviders `json:"providers"` Providers ServiceProviders `json:"providers"`

View File

@ -7,6 +7,9 @@ import (
"github.com/aerogo/nano" "github.com/aerogo/nano"
) )
// ThreadID represents a thread ID.
type ThreadID = ID
// Thread is a forum thread. // Thread is a forum thread.
type Thread struct { type Thread struct {
Title string `json:"title" editable:"true"` Title string `json:"title" editable:"true"`

View File

@ -33,7 +33,7 @@ func init() {
} }
// UserID represents a user ID. // UserID represents a user ID.
type UserID = string type UserID = ID
// User is a registered person. // User is a registered person.
type User struct { type User struct {

View File

@ -32,7 +32,7 @@ var (
) )
// GenerateID generates a unique ID for a given collection. // GenerateID generates a unique ID for a given collection.
func GenerateID(collection string) string { func GenerateID(collection string) ID {
id, _ := shortid.Generate() id, _ := shortid.Generate()
// Retry until we find an unused ID // Retry until we find an unused ID