feat(notes): saving the notes for any images for easy text searching
This commit is contained in:
18
backend/.gen/haystack/haystack/model/image_notes.go
Normal file
18
backend/.gen/haystack/haystack/model/image_notes.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Code generated by go-jet DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// WARNING: Changes to this file may cause incorrect behavior
|
||||||
|
// and will be lost if the code is regenerated
|
||||||
|
//
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ImageNotes struct {
|
||||||
|
ID uuid.UUID `sql:"primary_key"`
|
||||||
|
ImageID uuid.UUID
|
||||||
|
NoteID uuid.UUID
|
||||||
|
}
|
19
backend/.gen/haystack/haystack/model/notes.go
Normal file
19
backend/.gen/haystack/haystack/model/notes.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Code generated by go-jet DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// WARNING: Changes to this file may cause incorrect behavior
|
||||||
|
// and will be lost if the code is regenerated
|
||||||
|
//
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Notes struct {
|
||||||
|
ID uuid.UUID `sql:"primary_key"`
|
||||||
|
Name string
|
||||||
|
Description *string
|
||||||
|
Content string
|
||||||
|
}
|
18
backend/.gen/haystack/haystack/model/user_notes.go
Normal file
18
backend/.gen/haystack/haystack/model/user_notes.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Code generated by go-jet DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// WARNING: Changes to this file may cause incorrect behavior
|
||||||
|
// and will be lost if the code is regenerated
|
||||||
|
//
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserNotes struct {
|
||||||
|
ID uuid.UUID `sql:"primary_key"`
|
||||||
|
UserID uuid.UUID
|
||||||
|
NoteID uuid.UUID
|
||||||
|
}
|
81
backend/.gen/haystack/haystack/table/image_notes.go
Normal file
81
backend/.gen/haystack/haystack/table/image_notes.go
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//
|
||||||
|
// Code generated by go-jet DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// WARNING: Changes to this file may cause incorrect behavior
|
||||||
|
// and will be lost if the code is regenerated
|
||||||
|
//
|
||||||
|
|
||||||
|
package table
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-jet/jet/v2/postgres"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ImageNotes = newImageNotesTable("haystack", "image_notes", "")
|
||||||
|
|
||||||
|
type imageNotesTable struct {
|
||||||
|
postgres.Table
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
ID postgres.ColumnString
|
||||||
|
ImageID postgres.ColumnString
|
||||||
|
NoteID postgres.ColumnString
|
||||||
|
|
||||||
|
AllColumns postgres.ColumnList
|
||||||
|
MutableColumns postgres.ColumnList
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImageNotesTable struct {
|
||||||
|
imageNotesTable
|
||||||
|
|
||||||
|
EXCLUDED imageNotesTable
|
||||||
|
}
|
||||||
|
|
||||||
|
// AS creates new ImageNotesTable with assigned alias
|
||||||
|
func (a ImageNotesTable) AS(alias string) *ImageNotesTable {
|
||||||
|
return newImageNotesTable(a.SchemaName(), a.TableName(), alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schema creates new ImageNotesTable with assigned schema name
|
||||||
|
func (a ImageNotesTable) FromSchema(schemaName string) *ImageNotesTable {
|
||||||
|
return newImageNotesTable(schemaName, a.TableName(), a.Alias())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPrefix creates new ImageNotesTable with assigned table prefix
|
||||||
|
func (a ImageNotesTable) WithPrefix(prefix string) *ImageNotesTable {
|
||||||
|
return newImageNotesTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSuffix creates new ImageNotesTable with assigned table suffix
|
||||||
|
func (a ImageNotesTable) WithSuffix(suffix string) *ImageNotesTable {
|
||||||
|
return newImageNotesTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func newImageNotesTable(schemaName, tableName, alias string) *ImageNotesTable {
|
||||||
|
return &ImageNotesTable{
|
||||||
|
imageNotesTable: newImageNotesTableImpl(schemaName, tableName, alias),
|
||||||
|
EXCLUDED: newImageNotesTableImpl("", "excluded", ""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newImageNotesTableImpl(schemaName, tableName, alias string) imageNotesTable {
|
||||||
|
var (
|
||||||
|
IDColumn = postgres.StringColumn("id")
|
||||||
|
ImageIDColumn = postgres.StringColumn("image_id")
|
||||||
|
NoteIDColumn = postgres.StringColumn("note_id")
|
||||||
|
allColumns = postgres.ColumnList{IDColumn, ImageIDColumn, NoteIDColumn}
|
||||||
|
mutableColumns = postgres.ColumnList{ImageIDColumn, NoteIDColumn}
|
||||||
|
)
|
||||||
|
|
||||||
|
return imageNotesTable{
|
||||||
|
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
|
||||||
|
|
||||||
|
//Columns
|
||||||
|
ID: IDColumn,
|
||||||
|
ImageID: ImageIDColumn,
|
||||||
|
NoteID: NoteIDColumn,
|
||||||
|
|
||||||
|
AllColumns: allColumns,
|
||||||
|
MutableColumns: mutableColumns,
|
||||||
|
}
|
||||||
|
}
|
84
backend/.gen/haystack/haystack/table/notes.go
Normal file
84
backend/.gen/haystack/haystack/table/notes.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
//
|
||||||
|
// Code generated by go-jet DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// WARNING: Changes to this file may cause incorrect behavior
|
||||||
|
// and will be lost if the code is regenerated
|
||||||
|
//
|
||||||
|
|
||||||
|
package table
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-jet/jet/v2/postgres"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Notes = newNotesTable("haystack", "notes", "")
|
||||||
|
|
||||||
|
type notesTable struct {
|
||||||
|
postgres.Table
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
ID postgres.ColumnString
|
||||||
|
Name postgres.ColumnString
|
||||||
|
Description postgres.ColumnString
|
||||||
|
Content postgres.ColumnString
|
||||||
|
|
||||||
|
AllColumns postgres.ColumnList
|
||||||
|
MutableColumns postgres.ColumnList
|
||||||
|
}
|
||||||
|
|
||||||
|
type NotesTable struct {
|
||||||
|
notesTable
|
||||||
|
|
||||||
|
EXCLUDED notesTable
|
||||||
|
}
|
||||||
|
|
||||||
|
// AS creates new NotesTable with assigned alias
|
||||||
|
func (a NotesTable) AS(alias string) *NotesTable {
|
||||||
|
return newNotesTable(a.SchemaName(), a.TableName(), alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schema creates new NotesTable with assigned schema name
|
||||||
|
func (a NotesTable) FromSchema(schemaName string) *NotesTable {
|
||||||
|
return newNotesTable(schemaName, a.TableName(), a.Alias())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPrefix creates new NotesTable with assigned table prefix
|
||||||
|
func (a NotesTable) WithPrefix(prefix string) *NotesTable {
|
||||||
|
return newNotesTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSuffix creates new NotesTable with assigned table suffix
|
||||||
|
func (a NotesTable) WithSuffix(suffix string) *NotesTable {
|
||||||
|
return newNotesTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func newNotesTable(schemaName, tableName, alias string) *NotesTable {
|
||||||
|
return &NotesTable{
|
||||||
|
notesTable: newNotesTableImpl(schemaName, tableName, alias),
|
||||||
|
EXCLUDED: newNotesTableImpl("", "excluded", ""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newNotesTableImpl(schemaName, tableName, alias string) notesTable {
|
||||||
|
var (
|
||||||
|
IDColumn = postgres.StringColumn("id")
|
||||||
|
NameColumn = postgres.StringColumn("name")
|
||||||
|
DescriptionColumn = postgres.StringColumn("description")
|
||||||
|
ContentColumn = postgres.StringColumn("content")
|
||||||
|
allColumns = postgres.ColumnList{IDColumn, NameColumn, DescriptionColumn, ContentColumn}
|
||||||
|
mutableColumns = postgres.ColumnList{NameColumn, DescriptionColumn, ContentColumn}
|
||||||
|
)
|
||||||
|
|
||||||
|
return notesTable{
|
||||||
|
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
|
||||||
|
|
||||||
|
//Columns
|
||||||
|
ID: IDColumn,
|
||||||
|
Name: NameColumn,
|
||||||
|
Description: DescriptionColumn,
|
||||||
|
Content: ContentColumn,
|
||||||
|
|
||||||
|
AllColumns: allColumns,
|
||||||
|
MutableColumns: mutableColumns,
|
||||||
|
}
|
||||||
|
}
|
@ -17,14 +17,17 @@ func UseSchema(schema string) {
|
|||||||
ImageEvents = ImageEvents.FromSchema(schema)
|
ImageEvents = ImageEvents.FromSchema(schema)
|
||||||
ImageLinks = ImageLinks.FromSchema(schema)
|
ImageLinks = ImageLinks.FromSchema(schema)
|
||||||
ImageLocations = ImageLocations.FromSchema(schema)
|
ImageLocations = ImageLocations.FromSchema(schema)
|
||||||
|
ImageNotes = ImageNotes.FromSchema(schema)
|
||||||
ImageTags = ImageTags.FromSchema(schema)
|
ImageTags = ImageTags.FromSchema(schema)
|
||||||
ImageText = ImageText.FromSchema(schema)
|
ImageText = ImageText.FromSchema(schema)
|
||||||
Locations = Locations.FromSchema(schema)
|
Locations = Locations.FromSchema(schema)
|
||||||
|
Notes = Notes.FromSchema(schema)
|
||||||
UserContacts = UserContacts.FromSchema(schema)
|
UserContacts = UserContacts.FromSchema(schema)
|
||||||
UserEvents = UserEvents.FromSchema(schema)
|
UserEvents = UserEvents.FromSchema(schema)
|
||||||
UserImages = UserImages.FromSchema(schema)
|
UserImages = UserImages.FromSchema(schema)
|
||||||
UserImagesToProcess = UserImagesToProcess.FromSchema(schema)
|
UserImagesToProcess = UserImagesToProcess.FromSchema(schema)
|
||||||
UserLocations = UserLocations.FromSchema(schema)
|
UserLocations = UserLocations.FromSchema(schema)
|
||||||
|
UserNotes = UserNotes.FromSchema(schema)
|
||||||
UserTags = UserTags.FromSchema(schema)
|
UserTags = UserTags.FromSchema(schema)
|
||||||
Users = Users.FromSchema(schema)
|
Users = Users.FromSchema(schema)
|
||||||
}
|
}
|
||||||
|
81
backend/.gen/haystack/haystack/table/user_notes.go
Normal file
81
backend/.gen/haystack/haystack/table/user_notes.go
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//
|
||||||
|
// Code generated by go-jet DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// WARNING: Changes to this file may cause incorrect behavior
|
||||||
|
// and will be lost if the code is regenerated
|
||||||
|
//
|
||||||
|
|
||||||
|
package table
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-jet/jet/v2/postgres"
|
||||||
|
)
|
||||||
|
|
||||||
|
var UserNotes = newUserNotesTable("haystack", "user_notes", "")
|
||||||
|
|
||||||
|
type userNotesTable struct {
|
||||||
|
postgres.Table
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
ID postgres.ColumnString
|
||||||
|
UserID postgres.ColumnString
|
||||||
|
NoteID postgres.ColumnString
|
||||||
|
|
||||||
|
AllColumns postgres.ColumnList
|
||||||
|
MutableColumns postgres.ColumnList
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserNotesTable struct {
|
||||||
|
userNotesTable
|
||||||
|
|
||||||
|
EXCLUDED userNotesTable
|
||||||
|
}
|
||||||
|
|
||||||
|
// AS creates new UserNotesTable with assigned alias
|
||||||
|
func (a UserNotesTable) AS(alias string) *UserNotesTable {
|
||||||
|
return newUserNotesTable(a.SchemaName(), a.TableName(), alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schema creates new UserNotesTable with assigned schema name
|
||||||
|
func (a UserNotesTable) FromSchema(schemaName string) *UserNotesTable {
|
||||||
|
return newUserNotesTable(schemaName, a.TableName(), a.Alias())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPrefix creates new UserNotesTable with assigned table prefix
|
||||||
|
func (a UserNotesTable) WithPrefix(prefix string) *UserNotesTable {
|
||||||
|
return newUserNotesTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSuffix creates new UserNotesTable with assigned table suffix
|
||||||
|
func (a UserNotesTable) WithSuffix(suffix string) *UserNotesTable {
|
||||||
|
return newUserNotesTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func newUserNotesTable(schemaName, tableName, alias string) *UserNotesTable {
|
||||||
|
return &UserNotesTable{
|
||||||
|
userNotesTable: newUserNotesTableImpl(schemaName, tableName, alias),
|
||||||
|
EXCLUDED: newUserNotesTableImpl("", "excluded", ""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newUserNotesTableImpl(schemaName, tableName, alias string) userNotesTable {
|
||||||
|
var (
|
||||||
|
IDColumn = postgres.StringColumn("id")
|
||||||
|
UserIDColumn = postgres.StringColumn("user_id")
|
||||||
|
NoteIDColumn = postgres.StringColumn("note_id")
|
||||||
|
allColumns = postgres.ColumnList{IDColumn, UserIDColumn, NoteIDColumn}
|
||||||
|
mutableColumns = postgres.ColumnList{UserIDColumn, NoteIDColumn}
|
||||||
|
)
|
||||||
|
|
||||||
|
return userNotesTable{
|
||||||
|
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
|
||||||
|
|
||||||
|
//Columns
|
||||||
|
ID: IDColumn,
|
||||||
|
UserID: UserIDColumn,
|
||||||
|
NoteID: NoteIDColumn,
|
||||||
|
|
||||||
|
AllColumns: allColumns,
|
||||||
|
MutableColumns: mutableColumns,
|
||||||
|
}
|
||||||
|
}
|
@ -208,6 +208,7 @@ func (agent EventLocationAgent) GetLocations(userId uuid.UUID, imageId uuid.UUID
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: extract this into a more general tool handler package.
|
||||||
func (handler ToolsHandlers) Handle(info ToolHandlerInfo, request *AgentRequestBody) (string, error) {
|
func (handler ToolsHandlers) Handle(info ToolHandlerInfo, request *AgentRequestBody) (string, error) {
|
||||||
agentMessage := request.Messages[len(request.Messages)-1]
|
agentMessage := request.Messages[len(request.Messages)-1]
|
||||||
|
|
||||||
|
79
backend/agents/note_agent.go
Normal file
79
backend/agents/note_agent.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package agents
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"screenmark/screenmark/.gen/haystack/haystack/model"
|
||||||
|
"screenmark/screenmark/models"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
const noteAgentPrompt = `
|
||||||
|
You are a helpful agent, who's job is to extract notes from images.
|
||||||
|
Not all images contain notes, in such cases there's not need to create them.
|
||||||
|
|
||||||
|
An image can have more than one note.
|
||||||
|
|
||||||
|
You must return markdown, and adapt the text to best fit markdown.
|
||||||
|
Do not return anything except markdown.
|
||||||
|
`
|
||||||
|
|
||||||
|
type NoteAgent struct {
|
||||||
|
client AgentClient
|
||||||
|
|
||||||
|
noteModel models.NoteModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (agent NoteAgent) GetNotes(userId uuid.UUID, imageId uuid.UUID, imageName string, imageData []byte) error {
|
||||||
|
request := AgentRequestBody{
|
||||||
|
Model: "pixtral-12b-2409",
|
||||||
|
Temperature: 0.3,
|
||||||
|
ResponseFormat: ResponseFormat{
|
||||||
|
Type: "text",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := request.AddSystem(noteAgentPrompt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
request.AddImage(imageName, imageData)
|
||||||
|
resp, err := agent.client.Request(&request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
markdown := resp.Choices[0].Message.Content
|
||||||
|
|
||||||
|
note, err := agent.noteModel.Save(ctx, userId, model.Notes{
|
||||||
|
Name: "the note", // TODO: add some json schema
|
||||||
|
Content: markdown,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = agent.noteModel.SaveToImage(ctx, imageId, note.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNoteAgent(noteModel models.NoteModel) (NoteAgent, error) {
|
||||||
|
client, err := CreateAgentClient(noteAgentPrompt)
|
||||||
|
if err != nil {
|
||||||
|
return NoteAgent{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
agent := NoteAgent{
|
||||||
|
client: client,
|
||||||
|
noteModel: noteModel,
|
||||||
|
}
|
||||||
|
|
||||||
|
return agent, nil
|
||||||
|
}
|
@ -81,6 +81,7 @@ func main() {
|
|||||||
eventModel := models.NewEventModel(db)
|
eventModel := models.NewEventModel(db)
|
||||||
userModel := models.NewUserModel(db)
|
userModel := models.NewUserModel(db)
|
||||||
contactModel := models.NewContactModel(db)
|
contactModel := models.NewContactModel(db)
|
||||||
|
noteModel := models.NewNoteModel(db)
|
||||||
|
|
||||||
listener := pq.NewListener(os.Getenv("DB_CONNECTION"), time.Second, time.Second, func(event pq.ListenerEventType, err error) {
|
listener := pq.NewListener(os.Getenv("DB_CONNECTION"), time.Second, time.Second, func(event pq.ListenerEventType, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -109,7 +110,12 @@ func main() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
locationAgent, err := agents.NewLocationEventAgent(locationModel, eventModel, contactModel)
|
_, err = agents.NewLocationEventAgent(locationModel, eventModel, contactModel)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
noteAgent, err := agents.NewNoteAgent(noteModel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -128,8 +134,12 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Calling locationAgent!")
|
// log.Println("Calling locationAgent!")
|
||||||
err = locationAgent.GetLocations(image.UserID, image.ImageID, image.Image.ImageName, image.Image.Image)
|
// err = locationAgent.GetLocations(image.UserID, image.ImageID, image.Image.ImageName, image.Image.Image)
|
||||||
|
// log.Println(err)
|
||||||
|
|
||||||
|
log.Println("Calling noteAgent!")
|
||||||
|
err = noteAgent.GetNotes(image.UserID, image.ImageID, image.Image.ImageName, image.Image.Image)
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
67
backend/models/notes.go
Normal file
67
backend/models/notes.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"screenmark/screenmark/.gen/haystack/haystack/model"
|
||||||
|
. "screenmark/screenmark/.gen/haystack/haystack/table"
|
||||||
|
|
||||||
|
. "github.com/go-jet/jet/v2/postgres"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NoteModel struct {
|
||||||
|
dbPool *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m NoteModel) List(ctx context.Context, userId uuid.UUID) ([]model.Notes, error) {
|
||||||
|
listNotesStmt := SELECT(Notes.AllColumns).
|
||||||
|
FROM(
|
||||||
|
Notes.
|
||||||
|
INNER_JOIN(UserNotes, UserNotes.NoteID.EQ(Notes.ID)),
|
||||||
|
).
|
||||||
|
WHERE(UserNotes.UserID.EQ(UUID(userId)))
|
||||||
|
|
||||||
|
locations := []model.Notes{}
|
||||||
|
|
||||||
|
err := listNotesStmt.QueryContext(ctx, m.dbPool, &locations)
|
||||||
|
return locations, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m NoteModel) Save(ctx context.Context, userId uuid.UUID, note model.Notes) (model.Notes, error) {
|
||||||
|
insertNoteStmt := Notes.
|
||||||
|
INSERT(Notes.Name, Notes.Description, Notes.Content).
|
||||||
|
VALUES(note.Name, note.Description, note.Content).
|
||||||
|
RETURNING(Notes.AllColumns)
|
||||||
|
|
||||||
|
insertedNote := model.Notes{}
|
||||||
|
err := insertNoteStmt.QueryContext(ctx, m.dbPool, &insertedNote)
|
||||||
|
if err != nil {
|
||||||
|
return model.Notes{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
insertUserNoteStmt := UserNotes.
|
||||||
|
INSERT(UserNotes.UserID, UserNotes.NoteID).
|
||||||
|
VALUES(userId, insertedNote.ID)
|
||||||
|
|
||||||
|
_, err = insertUserNoteStmt.ExecContext(ctx, m.dbPool)
|
||||||
|
|
||||||
|
return insertedNote, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m NoteModel) SaveToImage(ctx context.Context, imageId uuid.UUID, noteId uuid.UUID) (model.ImageNotes, error) {
|
||||||
|
insertImageNoteStmt := ImageNotes.
|
||||||
|
INSERT(ImageNotes.ImageID, ImageNotes.NoteID).
|
||||||
|
VALUES(imageId, noteId).
|
||||||
|
RETURNING(ImageNotes.AllColumns)
|
||||||
|
|
||||||
|
imageNote := model.ImageNotes{}
|
||||||
|
err := insertImageNoteStmt.QueryContext(ctx, m.dbPool, &imageNote)
|
||||||
|
|
||||||
|
return imageNote, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNoteModel(db *sql.DB) NoteModel {
|
||||||
|
return NoteModel{dbPool: db}
|
||||||
|
}
|
@ -118,6 +118,28 @@ CREATE TABLE haystack.user_events (
|
|||||||
user_id UUID NOT NULL REFERENCES haystack.users (id)
|
user_id UUID NOT NULL REFERENCES haystack.users (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE haystack.notes (
|
||||||
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
|
||||||
|
-- It seems name and description are frequent. We could use table inheritance.
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
|
||||||
|
content TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE haystack.image_notes (
|
||||||
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
image_id UUID NOT NULL REFERENCES haystack.image (id),
|
||||||
|
note_id UUID NOT NULL REFERENCES haystack.notes (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE haystack.user_notes (
|
||||||
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
user_id UUID NOT NULL REFERENCES haystack.users (id),
|
||||||
|
note_id UUID NOT NULL REFERENCES haystack.notes (id)
|
||||||
|
);
|
||||||
|
|
||||||
/* -----| Indexes |----- */
|
/* -----| Indexes |----- */
|
||||||
|
|
||||||
CREATE INDEX user_tags_index ON haystack.user_tags(tag);
|
CREATE INDEX user_tags_index ON haystack.user_tags(tag);
|
||||||
|
Reference in New Issue
Block a user