Haystack V2: Removing entities completely
This commit is contained in:
@@ -1,117 +0,0 @@
|
||||
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 ContactModel struct {
|
||||
dbPool *sql.DB
|
||||
}
|
||||
|
||||
func (m ContactModel) List(ctx context.Context, userId uuid.UUID) ([]model.Contacts, error) {
|
||||
listContactsStmt := SELECT(Contacts.AllColumns).
|
||||
FROM(
|
||||
Contacts.
|
||||
INNER_JOIN(UserContacts, UserContacts.ContactID.EQ(Contacts.ID)),
|
||||
).
|
||||
WHERE(UserContacts.UserID.EQ(UUID(userId)))
|
||||
|
||||
locations := []model.Contacts{}
|
||||
|
||||
err := listContactsStmt.QueryContext(ctx, m.dbPool, &locations)
|
||||
return locations, err
|
||||
}
|
||||
|
||||
func (m ContactModel) Get(ctx context.Context, contactId uuid.UUID) (model.Contacts, error) {
|
||||
getContactStmt := Contacts.
|
||||
SELECT(Contacts.AllColumns).
|
||||
WHERE(Contacts.ID.EQ(UUID(contactId)))
|
||||
|
||||
contact := model.Contacts{}
|
||||
err := getContactStmt.QueryContext(ctx, m.dbPool, &contact)
|
||||
|
||||
return contact, err
|
||||
}
|
||||
|
||||
func (m ContactModel) Update(ctx context.Context, contact model.Contacts) (model.Contacts, error) {
|
||||
existingContact, err := m.Get(ctx, contact.ID)
|
||||
if err != nil {
|
||||
return model.Contacts{}, err
|
||||
}
|
||||
|
||||
existingContact.Name = contact.Name
|
||||
|
||||
if contact.Description != nil {
|
||||
existingContact.Description = contact.Description
|
||||
}
|
||||
|
||||
if contact.PhoneNumber != nil {
|
||||
existingContact.PhoneNumber = contact.PhoneNumber
|
||||
}
|
||||
|
||||
if contact.Email != nil {
|
||||
existingContact.Email = contact.Email
|
||||
}
|
||||
|
||||
updateContactStmt := Contacts.
|
||||
UPDATE(Contacts.MutableColumns).
|
||||
MODEL(existingContact).
|
||||
WHERE(Contacts.ID.EQ(UUID(contact.ID))).
|
||||
RETURNING(Contacts.AllColumns)
|
||||
|
||||
updatedContact := model.Contacts{}
|
||||
err = updateContactStmt.QueryContext(ctx, m.dbPool, &updatedContact)
|
||||
|
||||
return updatedContact, err
|
||||
}
|
||||
|
||||
func (m ContactModel) Save(ctx context.Context, userId uuid.UUID, contact model.Contacts) (model.Contacts, error) {
|
||||
// TODO: make this a transaction
|
||||
|
||||
if contact.ID != uuid.Nil {
|
||||
return m.Update(ctx, contact)
|
||||
}
|
||||
|
||||
insertContactStmt := Contacts.
|
||||
INSERT(Contacts.Name, Contacts.Description, Contacts.PhoneNumber, Contacts.Email).
|
||||
VALUES(contact.Name, contact.Description, contact.PhoneNumber, contact.Email).
|
||||
RETURNING(Contacts.AllColumns)
|
||||
|
||||
insertedContact := model.Contacts{}
|
||||
err := insertContactStmt.QueryContext(ctx, m.dbPool, &insertedContact)
|
||||
|
||||
if err != nil {
|
||||
return insertedContact, err
|
||||
}
|
||||
|
||||
insertUserContactStmt := UserContacts.
|
||||
INSERT(UserContacts.UserID, UserContacts.ContactID).
|
||||
VALUES(userId, insertedContact.ID)
|
||||
|
||||
_, err = insertUserContactStmt.ExecContext(ctx, m.dbPool)
|
||||
|
||||
return insertedContact, err
|
||||
}
|
||||
|
||||
func (m ContactModel) SaveToImage(ctx context.Context, imageId uuid.UUID, contactId uuid.UUID) (model.ImageContacts, error) {
|
||||
insertImageContactStmt := ImageContacts.
|
||||
INSERT(ImageContacts.ImageID, ImageContacts.ContactID).
|
||||
VALUES(imageId, contactId).
|
||||
RETURNING(ImageContacts.AllColumns)
|
||||
|
||||
imageContact := model.ImageContacts{}
|
||||
err := insertImageContactStmt.QueryContext(ctx, m.dbPool, &imageContact)
|
||||
|
||||
return imageContact, err
|
||||
}
|
||||
|
||||
func NewContactModel(db *sql.DB) ContactModel {
|
||||
return ContactModel{dbPool: db}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
. "github.com/go-jet/jet/v2/postgres"
|
||||
"screenmark/screenmark/.gen/haystack/haystack/model"
|
||||
. "screenmark/screenmark/.gen/haystack/haystack/table"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type EventModel struct {
|
||||
dbPool *sql.DB
|
||||
}
|
||||
|
||||
func (m EventModel) List(ctx context.Context, userId uuid.UUID) ([]model.Events, error) {
|
||||
listEventsStmt := SELECT(Events.AllColumns).
|
||||
FROM(
|
||||
Events.
|
||||
INNER_JOIN(UserEvents, UserEvents.EventID.EQ(Events.ID)),
|
||||
).
|
||||
WHERE(UserEvents.UserID.EQ(UUID(userId)))
|
||||
|
||||
events := []model.Events{}
|
||||
|
||||
err := listEventsStmt.QueryContext(ctx, m.dbPool, &events)
|
||||
return events, err
|
||||
}
|
||||
|
||||
func (m EventModel) Save(ctx context.Context, userId uuid.UUID, event model.Events) (model.Events, error) {
|
||||
// TODO tx here
|
||||
insertEventStmt := Events.
|
||||
INSERT(Events.MutableColumns).
|
||||
MODEL(event).
|
||||
RETURNING(Events.AllColumns)
|
||||
|
||||
insertedEvent := model.Events{}
|
||||
err := insertEventStmt.QueryContext(ctx, m.dbPool, &insertedEvent)
|
||||
|
||||
if err != nil {
|
||||
return insertedEvent, err
|
||||
}
|
||||
|
||||
insertUserEventStmt := UserEvents.
|
||||
INSERT(UserEvents.UserID, UserEvents.EventID).
|
||||
VALUES(userId, insertedEvent.ID)
|
||||
|
||||
_, err = insertUserEventStmt.ExecContext(ctx, m.dbPool)
|
||||
|
||||
return insertedEvent, err
|
||||
}
|
||||
|
||||
func (m EventModel) SaveToImage(ctx context.Context, imageId uuid.UUID, eventId uuid.UUID) (model.ImageEvents, error) {
|
||||
insertImageEventStmt := ImageEvents.
|
||||
INSERT(ImageEvents.ImageID, ImageEvents.EventID).
|
||||
VALUES(imageId, eventId).
|
||||
RETURNING(ImageEvents.AllColumns)
|
||||
|
||||
imageEvent := model.ImageEvents{}
|
||||
err := insertImageEventStmt.QueryContext(ctx, m.dbPool, &imageEvent)
|
||||
|
||||
return imageEvent, err
|
||||
}
|
||||
|
||||
func (m EventModel) UpdateLocation(ctx context.Context, eventId uuid.UUID, locationId uuid.UUID) (model.Events, error) {
|
||||
updateEventLocationStmt := Events.
|
||||
UPDATE(Events.LocationID).
|
||||
SET(locationId).
|
||||
WHERE(Events.ID.EQ(UUID(eventId))).
|
||||
RETURNING(Events.AllColumns)
|
||||
|
||||
updatedEvent := model.Events{}
|
||||
err := updateEventLocationStmt.QueryContext(ctx, m.dbPool, &updatedEvent)
|
||||
|
||||
return updatedEvent, err
|
||||
}
|
||||
|
||||
func (m EventModel) UpdateOrganizer(ctx context.Context, eventId uuid.UUID, organizerId uuid.UUID) (model.Events, error) {
|
||||
updateEventContactStmt := Events.
|
||||
UPDATE(Events.OrganizerID).
|
||||
SET(organizerId).
|
||||
WHERE(Events.ID.EQ(UUID(eventId))).
|
||||
RETURNING(Events.AllColumns)
|
||||
|
||||
updatedEvent := model.Events{}
|
||||
err := updateEventContactStmt.QueryContext(ctx, m.dbPool, &updatedEvent)
|
||||
|
||||
return updatedEvent, err
|
||||
}
|
||||
|
||||
func NewEventModel(db *sql.DB) EventModel {
|
||||
return EventModel{dbPool: db}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
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/go-jet/jet/v2/qrm"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type LocationModel struct {
|
||||
dbPool *sql.DB
|
||||
}
|
||||
|
||||
func (m LocationModel) List(ctx context.Context, userId uuid.UUID) ([]model.Locations, error) {
|
||||
listLocationsStmt := SELECT(Locations.AllColumns).
|
||||
FROM(
|
||||
Locations.
|
||||
INNER_JOIN(UserLocations, UserLocations.LocationID.EQ(Locations.ID)),
|
||||
).
|
||||
WHERE(UserLocations.UserID.EQ(UUID(userId)))
|
||||
|
||||
locations := []model.Locations{}
|
||||
|
||||
err := listLocationsStmt.QueryContext(ctx, m.dbPool, &locations)
|
||||
return locations, err
|
||||
}
|
||||
|
||||
func (m LocationModel) Get(ctx context.Context, locationId uuid.UUID) (model.Locations, error) {
|
||||
getLocationStmt := Locations.
|
||||
SELECT(Locations.AllColumns).
|
||||
WHERE(Locations.ID.EQ(UUID(locationId)))
|
||||
|
||||
location := model.Locations{}
|
||||
err := getLocationStmt.QueryContext(ctx, m.dbPool, &location)
|
||||
|
||||
return location, err
|
||||
}
|
||||
|
||||
func (m LocationModel) Update(ctx context.Context, location model.Locations) (model.Locations, error) {
|
||||
existingLocation, err := m.Get(ctx, location.ID)
|
||||
if err != nil {
|
||||
return model.Locations{}, err
|
||||
}
|
||||
|
||||
existingLocation.Name = location.Name
|
||||
|
||||
if location.Description != nil {
|
||||
existingLocation.Description = location.Description
|
||||
}
|
||||
|
||||
if location.Address != nil {
|
||||
existingLocation.Address = location.Address
|
||||
}
|
||||
|
||||
updateLocationStmt := Locations.
|
||||
UPDATE(Locations.MutableColumns).
|
||||
MODEL(existingLocation).
|
||||
WHERE(Locations.ID.EQ(UUID(location.ID))).
|
||||
RETURNING(Locations.AllColumns)
|
||||
|
||||
updatedLocation := model.Locations{}
|
||||
err = updateLocationStmt.QueryContext(ctx, m.dbPool, &updatedLocation)
|
||||
|
||||
return updatedLocation, err
|
||||
}
|
||||
|
||||
func (m LocationModel) Save(ctx context.Context, userId uuid.UUID, location model.Locations) (model.Locations, error) {
|
||||
if location.ID != uuid.Nil {
|
||||
return m.Update(ctx, location)
|
||||
}
|
||||
|
||||
insertLocationStmt := Locations.
|
||||
INSERT(Locations.Name, Locations.Address, Locations.Description).
|
||||
VALUES(location.Name, location.Address, location.Description).
|
||||
RETURNING(Locations.AllColumns)
|
||||
|
||||
insertedLocation := model.Locations{}
|
||||
err := insertLocationStmt.QueryContext(ctx, m.dbPool, &insertedLocation)
|
||||
if err != nil {
|
||||
return model.Locations{}, err
|
||||
}
|
||||
|
||||
insertUserLocationStmt := UserLocations.
|
||||
INSERT(UserLocations.UserID, UserLocations.LocationID).
|
||||
VALUES(userId, insertedLocation.ID)
|
||||
|
||||
_, err = insertUserLocationStmt.ExecContext(ctx, m.dbPool)
|
||||
|
||||
return insertedLocation, err
|
||||
}
|
||||
|
||||
func (m LocationModel) SaveToImage(ctx context.Context, imageId uuid.UUID, locationId uuid.UUID) (model.ImageLocations, error) {
|
||||
imageLocation := model.ImageLocations{}
|
||||
|
||||
checkExistingStmt := ImageLocations.
|
||||
SELECT(ImageLocations.AllColumns).
|
||||
WHERE(
|
||||
ImageLocations.ImageID.EQ(UUID(imageId)).
|
||||
AND(ImageLocations.LocationID.EQ(UUID(locationId))),
|
||||
)
|
||||
|
||||
err := checkExistingStmt.QueryContext(ctx, m.dbPool, &imageLocation)
|
||||
if err != nil && err != qrm.ErrNoRows {
|
||||
// A real error
|
||||
return model.ImageLocations{}, err
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
// Already exists.
|
||||
return imageLocation, nil
|
||||
}
|
||||
|
||||
insertImageLocationStmt := ImageLocations.
|
||||
INSERT(ImageLocations.ImageID, ImageLocations.LocationID).
|
||||
VALUES(imageId, locationId).
|
||||
RETURNING(ImageLocations.AllColumns)
|
||||
|
||||
err = insertImageLocationStmt.QueryContext(ctx, m.dbPool, &imageLocation)
|
||||
|
||||
return imageLocation, err
|
||||
}
|
||||
|
||||
func NewLocationModel(db *sql.DB) LocationModel {
|
||||
return LocationModel{dbPool: db}
|
||||
}
|
||||
@@ -19,189 +19,6 @@ type ImageWithProperties struct {
|
||||
ID uuid.UUID
|
||||
|
||||
Image model.Image
|
||||
|
||||
Locations []model.Locations
|
||||
Events []model.Events
|
||||
Contacts []model.Contacts
|
||||
}
|
||||
|
||||
type PropertiesWithImage struct {
|
||||
Locations []struct {
|
||||
model.Locations
|
||||
|
||||
Images uuid.UUIDs
|
||||
}
|
||||
Contacts []struct {
|
||||
model.Contacts
|
||||
|
||||
Images uuid.UUIDs
|
||||
}
|
||||
Events []struct {
|
||||
model.Events
|
||||
|
||||
Images uuid.UUIDs
|
||||
}
|
||||
}
|
||||
|
||||
func transpose(imageProperties []ImageWithProperties) PropertiesWithImage {
|
||||
// EntityID -> []ImageIDs
|
||||
dependencies := make(map[uuid.UUID]uuid.UUIDs)
|
||||
|
||||
addDependency := func(entityId uuid.UUID, imageId uuid.UUID) {
|
||||
deps, exists := dependencies[entityId]
|
||||
if !exists {
|
||||
dep := uuid.UUIDs{imageId}
|
||||
dependencies[entityId] = dep
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
dependencies[entityId] = append(deps, imageId)
|
||||
}
|
||||
|
||||
contactMap := make(map[uuid.UUID]model.Contacts)
|
||||
locationMap := make(map[uuid.UUID]model.Locations)
|
||||
eventMap := make(map[uuid.UUID]model.Events)
|
||||
|
||||
for _, image := range imageProperties {
|
||||
for _, contact := range image.Contacts {
|
||||
contactMap[contact.ID] = contact
|
||||
addDependency(contact.ID, image.Image.ID)
|
||||
}
|
||||
for _, location := range image.Locations {
|
||||
locationMap[location.ID] = location
|
||||
addDependency(location.ID, image.Image.ID)
|
||||
}
|
||||
for _, event := range image.Events {
|
||||
eventMap[event.ID] = event
|
||||
addDependency(event.ID, image.Image.ID)
|
||||
}
|
||||
}
|
||||
|
||||
properties := PropertiesWithImage{
|
||||
Contacts: make([]struct {
|
||||
model.Contacts
|
||||
Images uuid.UUIDs
|
||||
}, 0),
|
||||
Locations: make([]struct {
|
||||
model.Locations
|
||||
Images uuid.UUIDs
|
||||
}, 0),
|
||||
Events: make([]struct {
|
||||
model.Events
|
||||
Images uuid.UUIDs
|
||||
}, 0),
|
||||
}
|
||||
|
||||
for contactId, contact := range contactMap {
|
||||
properties.Contacts = append(properties.Contacts, struct {
|
||||
model.Contacts
|
||||
Images uuid.UUIDs
|
||||
}{
|
||||
Contacts: contact,
|
||||
Images: dependencies[contactId],
|
||||
})
|
||||
}
|
||||
|
||||
for locationId, location := range locationMap {
|
||||
properties.Locations = append(properties.Locations, struct {
|
||||
model.Locations
|
||||
Images uuid.UUIDs
|
||||
}{
|
||||
Locations: location,
|
||||
Images: dependencies[locationId],
|
||||
})
|
||||
}
|
||||
|
||||
for eventId, event := range eventMap {
|
||||
properties.Events = append(properties.Events, struct {
|
||||
model.Events
|
||||
Images uuid.UUIDs
|
||||
}{
|
||||
Events: event,
|
||||
Images: dependencies[eventId],
|
||||
})
|
||||
}
|
||||
|
||||
return properties
|
||||
}
|
||||
|
||||
type TypedProperties struct {
|
||||
Type string `json:"type"`
|
||||
Data any `json:"data"`
|
||||
}
|
||||
|
||||
func propertiesToTypeArray(properties PropertiesWithImage) []TypedProperties {
|
||||
typedProperties := make([]TypedProperties, 0)
|
||||
|
||||
for _, location := range properties.Locations {
|
||||
typedProperties = append(typedProperties, TypedProperties{
|
||||
Type: "location",
|
||||
Data: location,
|
||||
})
|
||||
}
|
||||
|
||||
for _, contact := range properties.Contacts {
|
||||
typedProperties = append(typedProperties, TypedProperties{
|
||||
Type: "contact",
|
||||
Data: contact,
|
||||
})
|
||||
}
|
||||
|
||||
for _, event := range properties.Events {
|
||||
typedProperties = append(typedProperties, TypedProperties{
|
||||
Type: "event",
|
||||
Data: event,
|
||||
})
|
||||
}
|
||||
|
||||
return typedProperties
|
||||
}
|
||||
|
||||
func GetTypedImageProperties(imageProperties []ImageWithProperties) []TypedProperties {
|
||||
return propertiesToTypeArray(transpose(imageProperties))
|
||||
}
|
||||
|
||||
func getListImagesStmt() SelectStatement {
|
||||
return SELECT(
|
||||
UserImages.ID.AS("ImageWithProperties.ID"),
|
||||
Image.ID,
|
||||
Image.ImageName,
|
||||
ImageLocations.AllColumns,
|
||||
Locations.AllColumns,
|
||||
ImageEvents.AllColumns,
|
||||
Events.AllColumns,
|
||||
ImageContacts.AllColumns,
|
||||
Contacts.AllColumns,
|
||||
).
|
||||
FROM(
|
||||
UserImages.INNER_JOIN(Image, Image.ID.EQ(UserImages.ImageID)).
|
||||
LEFT_JOIN(ImageLocations, ImageLocations.ImageID.EQ(UserImages.ImageID)).
|
||||
LEFT_JOIN(Locations, Locations.ID.EQ(ImageLocations.LocationID)).
|
||||
LEFT_JOIN(ImageEvents, ImageEvents.ImageID.EQ(UserImages.ImageID)).
|
||||
LEFT_JOIN(Events, Events.ID.EQ(ImageEvents.EventID)).
|
||||
LEFT_JOIN(ImageContacts, ImageContacts.ImageID.EQ(UserImages.ImageID)).
|
||||
LEFT_JOIN(Contacts, Contacts.ID.EQ(ImageContacts.ContactID)))
|
||||
}
|
||||
|
||||
func (m UserModel) ListImageWithProperties(ctx context.Context, userId uuid.UUID, imageId uuid.UUID) (ImageWithProperties, error) {
|
||||
listImagePropertiesStmt := getListImagesStmt().
|
||||
WHERE(UserImages.ImageID.EQ(UUID(imageId)))
|
||||
|
||||
image := ImageWithProperties{}
|
||||
err := listImagePropertiesStmt.QueryContext(ctx, m.dbPool, &image)
|
||||
|
||||
return image, err
|
||||
}
|
||||
|
||||
func (m UserModel) ListWithProperties(ctx context.Context, userId uuid.UUID) ([]ImageWithProperties, error) {
|
||||
listWithPropertiesStmt := getListImagesStmt().
|
||||
WHERE(UserImages.UserID.EQ(UUID(userId)))
|
||||
|
||||
images := []ImageWithProperties{}
|
||||
err := listWithPropertiesStmt.QueryContext(ctx, m.dbPool, &images)
|
||||
|
||||
return images, err
|
||||
}
|
||||
|
||||
func (m UserModel) GetUserIdFromEmail(ctx context.Context, email string) (uuid.UUID, error) {
|
||||
|
||||
Reference in New Issue
Block a user