Library/models/books_add_update.go

131 lines
3.2 KiB
Go

package models
/**
::USAGE::
Erwatet ein Struct mit einem Buch.
Wenn dieses Struct einen Publisher in Book.Publisher enthält und dieser existiert, wird diese
ID verwendet. Wenn die ID nicht existiert oder 0 ist, wird geguckt, ob der Publisher unter
Book.Publisher bereits existtiert (über die ID), ist das nicht der Fall, wird er in
die Datenbank eingetragen und mit dem Buch verknüpft.
Bei den Autoren wird ebenfalls überprüft, ob sie bereits existieren, wenn dem nicht so ist werden
sie in die Datenbank eingetragen und mit dem Buch verknüpft.
*/
// AddOrUpdateBook adds a new book or updates an existing one, it takes a book struct with author and publisher. Inserts them if they don't already exist
func AddOrUpdateBook(book Book, doer *User) (newBook Book, err error) {
// Check if we have at least a booktitle when we're inserting a new book
if book.Title == "" {
return Book{}, ErrBookTitleCannotBeEmpty{}
}
// Take Publisher, check if it exists. If not, insert it
exists := false
publisherid := book.PublisherID
if publisherid == 0 {
if book.Publisher.ID != 0 {
publisherid = book.Publisher.ID
}
}
_, exists, err = GetPublisherByID(publisherid)
if err != nil {
return Book{}, err
}
// If the publisher exists, make it the new publisher of the book
if exists {
book.PublisherID = publisherid
} else {
// Otherwise insert it and make it the new publisher afterwards
newPublisher, err := AddOrUpdatePublisher(Publisher{Name: book.Publisher.Name}, doer)
if err != nil {
return Book{}, err
}
book.PublisherID = newPublisher.ID
}
// Save the quantity for later use
qty := book.Quantity
// If we have an ID, try to update the book, otherwise create it
if book.ID == 0 {
// Insert the book
_, err = x.Insert(&book)
if err != nil {
return Book{}, err
}
// Log
err = logAction(ActionTypeBookAdded, doer, book.ID)
if err != nil {
return Book{}, err
}
} else {
// Update the book
_, err := x.Id(book.ID).Update(book)
if err != nil {
return Book{}, err
}
// Log
err = logAction(ActionTypeBookUpdated, doer, book.ID)
if err != nil {
return Book{}, err
}
}
// Set the Quantity
err = book.setQuantity(qty)
if err != nil {
return Book{}, err
}
// Delete all (maybe) previously existing author relations
x.Delete(AuthorBook{BookID: book.ID})
// Take the authors, look if they exist, if they don't create them
authorBookRelation := make([]AuthorBook, 0)
for _, author := range book.Authors {
_, exists, err := GetAuthorByID(author.ID)
if err != nil {
return Book{}, err
}
if !exists {
// We have to insert authors on this inperformant way, because we need the new ids afterwards
insertedAuthor, err := AddOrUpdateAuthor(author, doer)
if err != nil {
return Book{}, err
}
author.ID = insertedAuthor.ID
}
// Prepare new author Relation
authorBookRelation = append(authorBookRelation, AuthorBook{BookID: book.ID, AuthorID: author.ID})
}
// Insert the connection between the author and the book
_, err = x.Insert(&authorBookRelation)
if err != nil {
return Book{}, err
}
// Get the newly inserted book
newBook, _, err = GetBookByID(book.ID)
return newBook, err
}