diff --git a/db/dberrors/note_image.bob.go b/db/dberrors/note_image.bob.go index bc6f8f40..9b32ac13 100644 --- a/db/dberrors/note_image.bob.go +++ b/db/dberrors/note_image.bob.go @@ -10,8 +10,17 @@ var NoteImageErrors = ¬eImageErrors{ columns: []string{"version", "uuid"}, s: "note_image_pkey", }, + + ErrUniqueNoteImageIdUnique: &UniqueConstraintError{ + schema: "", + table: "note_image", + columns: []string{"id"}, + s: "note_image_id_unique", + }, } type noteImageErrors struct { ErrUniqueNoteImagePkey *UniqueConstraintError + + ErrUniqueNoteImageIdUnique *UniqueConstraintError } diff --git a/db/dbinfo/note_image.bob.go b/db/dbinfo/note_image.bob.go index 2a48e71a..12176a7d 100644 --- a/db/dbinfo/note_image.bob.go +++ b/db/dbinfo/note_image.bob.go @@ -78,6 +78,15 @@ var NoteImages = Table[ Generated: false, AutoIncr: false, }, + ID: column{ + Name: "id", + DBType: "integer", + Default: "IDENTITY", + Comment: "", + Nullable: false, + Generated: true, + AutoIncr: false, + }, }, Indexes: noteImageIndexes{ NoteImagePkey: index{ @@ -102,6 +111,23 @@ var NoteImages = Table[ Where: "", Include: []string{}, }, + NoteImageIDUnique: index{ + Type: "btree", + Name: "note_image_id_unique", + Columns: []indexColumn{ + { + Name: "id", + Desc: null.FromCond(false, true), + IsExpression: false, + }, + }, + Unique: true, + Comment: "", + NullsFirst: []bool{false}, + NullsDistinct: false, + Where: "", + Include: []string{}, + }, }, PrimaryKey: &constraint{ Name: "note_image_pkey", @@ -137,6 +163,13 @@ var NoteImages = Table[ ForeignColumns: []string{"id"}, }, }, + Uniques: noteImageUniques{ + NoteImageIDUnique: constraint{ + Name: "note_image_id_unique", + Columns: []string{"id"}, + Comment: "", + }, + }, Comment: "", } @@ -149,21 +182,23 @@ type noteImageColumns struct { OrganizationID column Version column UUID column + ID column } func (c noteImageColumns) AsSlice() []column { return []column{ - c.Created, c.CreatorID, c.Deleted, c.DeletorID, c.OrganizationID, c.Version, c.UUID, + c.Created, c.CreatorID, c.Deleted, c.DeletorID, c.OrganizationID, c.Version, c.UUID, c.ID, } } type noteImageIndexes struct { - NoteImagePkey index + NoteImagePkey index + NoteImageIDUnique index } func (i noteImageIndexes) AsSlice() []index { return []index{ - i.NoteImagePkey, + i.NoteImagePkey, i.NoteImageIDUnique, } } @@ -179,10 +214,14 @@ func (f noteImageForeignKeys) AsSlice() []foreignKey { } } -type noteImageUniques struct{} +type noteImageUniques struct { + NoteImageIDUnique constraint +} func (u noteImageUniques) AsSlice() []constraint { - return []constraint{} + return []constraint{ + u.NoteImageIDUnique, + } } type noteImageChecks struct{} diff --git a/db/migrations/00121_note_image_id.sql b/db/migrations/00121_note_image_id.sql new file mode 100644 index 00000000..f21c1cb0 --- /dev/null +++ b/db/migrations/00121_note_image_id.sql @@ -0,0 +1,7 @@ +-- +goose Up +ALTER TABLE note_image +ADD COLUMN id INTEGER GENERATED ALWAYS AS IDENTITY; +ALTER TABLE note_image +ADD CONSTRAINT note_image_id_unique UNIQUE (id); +-- +goose Down +ALTER TABLE note_image DROP COLUMN id; diff --git a/db/models/note_image.bob.go b/db/models/note_image.bob.go index 31952424..c4b900ce 100644 --- a/db/models/note_image.bob.go +++ b/db/models/note_image.bob.go @@ -33,6 +33,7 @@ type NoteImage struct { OrganizationID int32 `db:"organization_id" ` Version int32 `db:"version,pk" ` UUID uuid.UUID `db:"uuid,pk" ` + ID int32 `db:"id,generated" ` R noteImageR `db:"-" ` } @@ -59,7 +60,7 @@ type noteImageR struct { func buildNoteImageColumns(alias string) noteImageColumns { return noteImageColumns{ ColumnsExpr: expr.NewColumnsExpr( - "created", "creator_id", "deleted", "deletor_id", "organization_id", "version", "uuid", + "created", "creator_id", "deleted", "deletor_id", "organization_id", "version", "uuid", "id", ).WithParent("note_image"), tableAlias: alias, Created: psql.Quote(alias, "created"), @@ -69,6 +70,7 @@ func buildNoteImageColumns(alias string) noteImageColumns { OrganizationID: psql.Quote(alias, "organization_id"), Version: psql.Quote(alias, "version"), UUID: psql.Quote(alias, "uuid"), + ID: psql.Quote(alias, "id"), } } @@ -82,6 +84,7 @@ type noteImageColumns struct { OrganizationID psql.Expression Version psql.Expression UUID psql.Expression + ID psql.Expression } func (c noteImageColumns) Alias() string { @@ -920,6 +923,7 @@ type noteImageWhere[Q psql.Filterable] struct { OrganizationID psql.WhereMod[Q, int32] Version psql.WhereMod[Q, int32] UUID psql.WhereMod[Q, uuid.UUID] + ID psql.WhereMod[Q, int32] } func (noteImageWhere[Q]) AliasedAs(alias string) noteImageWhere[Q] { @@ -935,6 +939,7 @@ func buildNoteImageWhere[Q psql.Filterable](cols noteImageColumns) noteImageWher OrganizationID: psql.Where[Q, int32](cols.OrganizationID), Version: psql.Where[Q, int32](cols.Version), UUID: psql.Where[Q, uuid.UUID](cols.UUID), + ID: psql.Where[Q, int32](cols.ID), } } diff --git a/platform/event/event.go b/platform/event/event.go index 8d76aaaf..c6f2c778 100644 --- a/platform/event/event.go +++ b/platform/event/event.go @@ -84,6 +84,8 @@ type ResourceType int const ( TypeUnknown = iota TypeFileCSV + TypeNoteAudio + TypeNoteImage TypeReviewTask TypeRMONuisance TypeRMOReport @@ -120,6 +122,10 @@ func resourceString(t ResourceType) string { switch t { case TypeFileCSV: return "sync:filecsv" + case TypeNoteAudio: + return "sync:note:audio" + case TypeNoteImage: + return "sync:note:image" case TypeReviewTask: return "sync:review_task" case TypeRMONuisance: @@ -138,6 +144,10 @@ func makeURI(t ResourceType, id string) string { switch t { case TypeFileCSV: return config.MakeURLNidus("/upload/%s", id) + case TypeNoteAudio: + return config.MakeURLNidus("/note/%s", id) + case TypeNoteImage: + return config.MakeURLNidus("/note/%s", id) case TypeReviewTask: return config.MakeURLNidus("/review/%s", id) case TypeRMONuisance: diff --git a/platform/note.go b/platform/note.go index 4d1ba299..3f80c11e 100644 --- a/platform/note.go +++ b/platform/note.go @@ -3,43 +3,50 @@ package platform import ( "context" "fmt" + "strconv" "github.com/Gleipnir-Technology/nidus-sync/db" "github.com/Gleipnir-Technology/nidus-sync/db/models" - "github.com/google/uuid" - "github.com/rs/zerolog/log" + "github.com/Gleipnir-Technology/nidus-sync/platform/event" + //"github.com/google/uuid" + //"github.com/rs/zerolog/log" ) func NoteAudioCreate(ctx context.Context, user User, setter models.NoteAudioSetter) error { - _, err := models.NoteAudios.Insert(&setter).One(ctx, db.PGInstance.BobDB) + txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil) + if err != nil { + return fmt.Errorf("create txn: %w", err) + } + defer txn.Rollback(ctx) + + note_audio, err := models.NoteAudios.Insert(&setter).One(ctx, txn) if err != nil { // Just ignore this failure, it means we already have this content if err.Error() != "insertOrganizationNoteAudios0: ERROR: duplicate key value violates unique constraint \"note_audio_pkey\" (SQLSTATE 23505)" { return fmt.Errorf("create note_audio: %w", err) } } + event.Created(event.TypeNoteAudio, user.Organization.ID(), strconv.Itoa(int(note_audio.ID))) + txn.Commit(ctx) + return nil } -func NoteAudioNormalized(uuid string) error { - return nil -} -func NoteAudioTranscodedToOgg(uuid string) error { - return nil -} func NoteImageCreate(ctx context.Context, user User, setter models.NoteImageSetter) error { - _, err := models.NoteImages.Insert(&setter).One(ctx, db.PGInstance.BobDB) - if err == nil { - return nil + txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil) + if err != nil { + return fmt.Errorf("create txn: %w", err) } - // Just ignore this failure, it means we already have this content - if err.Error() == "insertOrganizationNoteImages0: ERROR: duplicate key value violates unique constraint \"note_image_pkey\" (SQLSTATE 23505)" { - return nil + defer txn.Rollback(ctx) + note_image, err := models.NoteImages.Insert(&setter).One(ctx, db.PGInstance.BobDB) + if err != nil { + // Just ignore this failure, it means we already have this content + if err.Error() != "insertOrganizationNoteImages0: ERROR: duplicate key value violates unique constraint \"note_image_pkey\" (SQLSTATE 23505)" { + return fmt.Errorf("create note_image: %w", err) + } } - log.Warn().Err(err).Msg("Unrecognized error creating note audio") + event.Created(event.TypeNoteImage, user.Organization.ID(), strconv.Itoa(int(note_image.ID))) + txn.Commit(ctx) + return err } - -func NoteUpdate(ctx context.Context, noteUUID uuid.UUID, setter models.NoteAudioSetter) error { - return nil -}