diff --git a/go.mod b/go.mod index a2ceed4..9dcb619 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/matoous/go-nanoid/v2 v2.1.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.18.0 // indirect diff --git a/go.sum b/go.sum index 7d29fd6..f00d304 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/matoous/go-nanoid/v2 v2.1.0 h1:P64+dmq21hhWdtvZfEAofnvJULaRR1Yib0+PnU669bE= +github.com/matoous/go-nanoid/v2 v2.1.0/go.mod h1:KlbGNQ+FhrUNIHUxZdL63t7tl4LaPkZNpUULS8H4uVM= github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/neo4j/neo4j-go-driver/v5 v5.17.0 h1:Bdqg1Y8Hd3uLYToXtBjysDYXTdMiP7zeUNUEwfbJkSo= diff --git a/internal/postgres/tag.go b/internal/postgres/tag.go new file mode 100644 index 0000000..1dc97b1 --- /dev/null +++ b/internal/postgres/tag.go @@ -0,0 +1,38 @@ +package postgres + +import ( + "context" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" + "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" + log "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +func CreateTagNodeWitRelation(ctx context.Context, db *gorm.DB, PostID models.AnthrovePostID, tag *pgModels.Tag) error { + + resultTag := db.WithContext(ctx).Where(tag).FirstOrCreate(tag) + + if resultTag.Error != nil { + return resultTag.Error + } + + pgPost := pgModels.Post{ + BaseModel: pgModels.BaseModel{ + ID: string(PostID), + }, + } + + err := db.WithContext(ctx).Model(pgPost).Association("Tags").Append(tag) + + if err != nil { + return err + } + + log.WithFields(log.Fields{ + "anthrove_post_id": PostID, + "tag_name": tag.Name, + "tag_type": tag.Type, + }).Trace("database: created tag node") + + return nil +} diff --git a/internal/utils/modelConvert.go b/internal/utils/modelConvert.go index cc75258..080af20 100644 --- a/internal/utils/modelConvert.go +++ b/internal/utils/modelConvert.go @@ -1,6 +1,7 @@ package utils import ( + "git.dragse.it/anthrove/otter-space-sdk/pkg/models" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/graphModels" "git.dragse.it/anthrove/otter-space-sdk/pkg/models/pgModels" ) @@ -25,3 +26,22 @@ func PostgresConvertToAnthroveSource(pgSource *pgModels.Source) *graphModels.Ant return graphSource } + +// GraphConvertTag converts a graphModels.AnthroveTag to a pgModels.Tag +func GraphConvertTag(graphTag *graphModels.AnthroveTag) *pgModels.Tag { + pgTag := &pgModels.Tag{ + Name: graphTag.Name, + Type: models.TagType(graphTag.Type), + } + return pgTag +} + +// PostgresConvertToAnthroveTag converts a pgModels.Tag to a graphModels.AnthroveTag +func PostgresConvertToAnthroveTag(pgTag *pgModels.Tag) *graphModels.AnthroveTag { + graphTag := &graphModels.AnthroveTag{ + Name: pgTag.Name, + Type: string(pgTag.Type), + } + + return graphTag +} diff --git a/pkg/database/migrations/001_inital_database.sql b/pkg/database/migrations/001_inital_database.sql index 00fcf9c..66770a1 100644 --- a/pkg/database/migrations/001_inital_database.sql +++ b/pkg/database/migrations/001_inital_database.sql @@ -1,9 +1,3 @@ --- TODO: Add the following fields where its defined in the model --- created_at --- updated_at --- deleted_at - - -- +migrate Up CREATE TYPE Rating AS ENUM ( 'safe', @@ -23,29 +17,39 @@ CREATE TYPE TagType AS ENUM ( CREATE TABLE "Post" ( - id VARCHAR(25) UNIQUE PRIMARY KEY, + id CHAR(25) UNIQUE PRIMARY KEY, rating Rating, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL NULL ); CREATE TABLE "Source" ( - id VARCHAR(25) UNIQUE PRIMARY KEY, - display_name TEXT, - icon TEXT, - domain TEXT NOT NULL UNIQUE + id CHAR(25) UNIQUE PRIMARY KEY, + display_name TEXT NULL, + icon TEXT NULL, + domain TEXT NOT NULL UNIQUE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL ); CREATE TABLE "Tag" ( - name TEXT PRIMARY KEY, - type TagType + name TEXT PRIMARY KEY, + tag_type TagType, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL ); CREATE TABLE "User" ( id TEXT UNIQUE PRIMARY KEY, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + deleted_at TIMESTAMP NULL ); CREATE TABLE "PostReference" @@ -59,20 +63,22 @@ CREATE TABLE "PostReference" CREATE TABLE "TagAlias" ( - name TEXT PRIMARY KEY, - tag_id TEXT REFERENCES "Tag" (name) + name TEXT PRIMARY KEY, + tag_id TEXT REFERENCES "Tag" (name), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE "TagGroup" ( - name TEXT PRIMARY KEY, - tag_id TEXT REFERENCES "Tag" (name) + name TEXT PRIMARY KEY, + tag_id TEXT REFERENCES "Tag" (name), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE "UserFavorites" ( - user_id TEXT REFERENCES "User" (id), - post_id TEXT REFERENCES "Post" (id), + user_id TEXT UNIQUE REFERENCES "User" (id), + post_id TEXT UNIQUE REFERENCES "Post" (id), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (user_id, post_id) ); @@ -83,18 +89,26 @@ CREATE TABLE "UserSource" source_id TEXT REFERENCES "Source" (id), account_username TEXT, account_id TEXT, - PRIMARY KEY (user_id, source_id) + PRIMARY KEY (user_id, source_id), + UNIQUE (account_username, account_id) +); + +CREATE TABLE "post_tags" +( + post_id TEXT REFERENCES "Post" (id), + tag_name TEXT REFERENCES "Tag" (name), + PRIMARY KEY (post_id, tag_name) ); -- +migrate Down DROP TYPE Rating; DROP TYPE TagType; -DROP TYPE Post; -DROP TYPE Source; -DROP TYPE Tag; -DROP TYPE User; -DROP TYPE PostReference; -DROP TYPE TagAlias; -DROP TYPE TagGroup; -DROP TYPE UserFavorites; -DROP TYPE UserSource; \ No newline at end of file +DROP TABLE Post; +DROP TABLE Source; +DROP TABLE Tag; +DROP TABLE User; +DROP TABLE PostReference; +DROP TABLE TagAlias; +DROP TABLE TagGroup; +DROP TABLE UserFavorites; +DROP TABLE UserSource; \ No newline at end of file diff --git a/pkg/database/postgres.go b/pkg/database/postgres.go index 5ed0afe..f1d8402 100644 --- a/pkg/database/postgres.go +++ b/pkg/database/postgres.go @@ -68,8 +68,7 @@ func (p *postgresqlConnection) AddPost(ctx context.Context, anthrovePost *graphM } func (p *postgresqlConnection) AddTagWithRelationToPost(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveTag *graphModels.AnthroveTag) error { - //TODO implement me - panic("implement me") + return postgres.CreateTagNodeWitRelation(ctx, p.db, anthrovePostID, utils.GraphConvertTag(anthroveTag)) } func (p *postgresqlConnection) LinkPostWithSource(ctx context.Context, anthrovePostID models.AnthrovePostID, anthroveSourceDomain string, anthrovePostRelationship *graphModels.AnthrovePostRelationship) error { diff --git a/pkg/models/pgModels/orm.go b/pkg/models/pgModels/orm.go index bea5f1b..11aafa4 100644 --- a/pkg/models/pgModels/orm.go +++ b/pkg/models/pgModels/orm.go @@ -1,6 +1,7 @@ package pgModels import ( + gonanoid "github.com/matoous/go-nanoid/v2" "gorm.io/gorm" "time" ) @@ -11,3 +12,14 @@ type BaseModel struct { UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` } + +func (base *BaseModel) BeforeCreate(db *gorm.DB) error { + id, err := gonanoid.New() + if err != nil { + return err + } + + base.ID = id + + return nil +} diff --git a/pkg/models/pgModels/post.go b/pkg/models/pgModels/post.go index d2dd980..d5ea588 100644 --- a/pkg/models/pgModels/post.go +++ b/pkg/models/pgModels/post.go @@ -12,3 +12,7 @@ type Post struct { Favorites []UserFavorite `gorm:"foreignKey:PostID"` References []PostReference `gorm:"foreignKey:PostID"` } + +func (Post) TableName() string { + return "Post" +} diff --git a/pkg/models/pgModels/tag.go b/pkg/models/pgModels/tag.go index 406f744..7538ac9 100644 --- a/pkg/models/pgModels/tag.go +++ b/pkg/models/pgModels/tag.go @@ -4,11 +4,15 @@ import "git.dragse.it/anthrove/otter-space-sdk/pkg/models" // Tag models type Tag struct { - Name string `gorm:"primaryKey"` - Type models.TagType - Aliases []TagAlias `gorm:"foreignKey:TagID"` - Groups []TagGroup `gorm:"foreignKey:TagID"` - Posts []Post `gorm:"many2many:post_tags;"` + Name string `gorm:"primaryKey"` + Type models.TagType `gorm:"column:tag_type"` + Aliases []TagAlias `gorm:"foreignKey:TagID"` + Groups []TagGroup `gorm:"foreignKey:TagID"` + Posts []Post `gorm:"many2many:post_tags;"` +} + +func (Tag) TableName() string { + return "Tag" } // TagAlias model @@ -17,8 +21,16 @@ type TagAlias struct { TagID string } +func (TagAlias) TableName() string { + return "TagAlias" +} + // TagGroup model type TagGroup struct { Name string `gorm:"primaryKey"` TagID string } + +func (TagGroup) TableName() string { + return "TagGroup" +}