diff --git a/demodata.sql b/demodata.sql
index 43bf7be..6c5cdee 100644
--- a/demodata.sql
+++ b/demodata.sql
@@ -132,18 +132,18 @@ INSERT INTO collections(name, user_id) VALUES ('Nouvelles',(SELECT id FROM users
INSERT INTO collections(name, user_id) VALUES ('Non fiction',(SELECT id FROM users WHERE name = 'demo2'));
INSERT INTO collections(name, user_id) VALUES ('Empty',(SELECT id FROM users WHERE name = 'demo'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Nord'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Gargantua'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Duo'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Un barrage contre le Pacifique'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Rigodon'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Les dieux ont soif'));
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Nord'), 1);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Gargantua'), 2);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Duo'), 3);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Un barrage contre le Pacifique'), 4);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Rigodon'), 5);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Littérature française'), (SELECT id FROM books WHERE title = 'Les dieux ont soif'), 6);
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Nouvelles'), (SELECT id FROM books WHERE title = 'Dojoji et autres nouvelles'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Nouvelles'), (SELECT id FROM books WHERE title = 'Le meurtre d''O-tsuya'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Nouvelles'), (SELECT id FROM books WHERE title = 'Le coup de pistolet'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Nouvelles'), (SELECT id FROM books WHERE title = 'Duo'));
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Nouvelles'), (SELECT id FROM books WHERE title = 'Dojoji et autres nouvelles'), 1);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Nouvelles'), (SELECT id FROM books WHERE title = 'Le meurtre d''O-tsuya'), 2);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Nouvelles'), (SELECT id FROM books WHERE title = 'Le coup de pistolet'), 3);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Nouvelles'), (SELECT id FROM books WHERE title = 'Duo'), 3);
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Non fiction'), (SELECT id FROM books WHERE title = 'Recherches philosophiques'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Non fiction'), (SELECT id FROM books WHERE title = 'De sang-froid'));
-INSERT INTO collection_books(collection_id, book_id) VALUES ((SELECT id FROM collections WHERE name = 'Non fiction'), (SELECT id FROM books WHERE title = 'The Life of Jesus'));
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Non fiction'), (SELECT id FROM books WHERE title = 'Recherches philosophiques'), 1);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Non fiction'), (SELECT id FROM books WHERE title = 'De sang-froid'), 2);
+INSERT INTO collection_items(collection_id, book_id, position) VALUES ((SELECT id FROM collections WHERE name = 'Non fiction'), (SELECT id FROM books WHERE title = 'The Life of Jesus'), 3);
diff --git a/front/src/BookListElement.vue b/front/src/BookListElement.vue
index 729ea20..bf04ea9 100644
--- a/front/src/BookListElement.vue
+++ b/front/src/BookListElement.vue
@@ -164,6 +164,7 @@ async function importInventaireEdition(inventaireid) {
+
diff --git a/front/src/CollectionForm.vue b/front/src/CollectionForm.vue
index 163fce9..1c25056 100644
--- a/front/src/CollectionForm.vue
+++ b/front/src/CollectionForm.vue
@@ -1,7 +1,7 @@
+
+
+
+
+
+ {{ props.position }}
+
+
+
+
+
+
+
+
+
+
diff --git a/internal/adapter/adapter.go b/internal/adapter/adapter.go
index 4ff2ad6..bef0656 100644
--- a/internal/adapter/adapter.go
+++ b/internal/adapter/adapter.go
@@ -10,12 +10,37 @@ import (
"gorm.io/gorm"
)
-func CollectionQueryToCollectionItemDto(collectionsQueryResult []query.CollectionsQueryResult) []dto.CollectionItemGet {
- var collections []dto.CollectionItemGet
+func CollectionItemsQueryToDto(itemsQueryResult []query.CollectionItemQueryResult) []dto.CollectionItemGet {
+ var dtoItems []dto.CollectionItemGet
+ for _, queryResult := range itemsQueryResult {
+ bookItem := dto.BookItemGet{
+ ID: queryResult.ID,
+ Title: queryResult.Title,
+ Author: queryResult.Author,
+ Description: queryResult.Description,
+ InventaireID: queryResult.InventaireID,
+ IsInventaireEdition: queryResult.IsInventaireEdition,
+ Rating: queryResult.Rating,
+ Read: queryResult.Read,
+ StartReadDate: queryResult.StartReadDate,
+ WantRead: queryResult.WantRead,
+ CoverPath: queryResult.CoverPath,
+ }
+ dtoItems = append(dtoItems,
+ dto.CollectionItemGet{
+ Position: queryResult.Position,
+ Book: bookItem,
+ })
+ }
+ return dtoItems
+}
+
+func CollectionQueryToCollectionItemDto(collectionsQueryResult []query.CollectionsQueryResult) []dto.CollectionListItemGet {
+ var collections []dto.CollectionListItemGet
for _, collectionDb := range collectionsQueryResult {
i := findIdInCollection(collections, collectionDb.ID)
if i == -1 {
- collections = append(collections, dto.CollectionItemGet{
+ collections = append(collections, dto.CollectionListItemGet{
ID: collectionDb.ID,
Name: collectionDb.Name,
})
@@ -30,9 +55,9 @@ func CollectionQueryToCollectionItemDto(collectionsQueryResult []query.Collectio
return collections
}
-func collectionDbToCollectionBookItem(collectionDb *query.CollectionsQueryResult) *dto.CollectionBookItemGet {
+func collectionDbToCollectionBookItem(collectionDb *query.CollectionsQueryResult) *dto.CollectionListBookItemGet {
if collectionDb.BookId > 0 {
- bookItem := dto.CollectionBookItemGet{
+ bookItem := dto.CollectionListBookItemGet{
ID: collectionDb.BookId,
Title: collectionDb.BookTitle,
CoverPath: collectionDb.CoverPath,
@@ -44,7 +69,7 @@ func collectionDbToCollectionBookItem(collectionDb *query.CollectionsQueryResult
}
// returns the position in collections, -1 if not found
-func findIdInCollection(collections []dto.CollectionItemGet, collectionId uint) int {
+func findIdInCollection(collections []dto.CollectionListItemGet, collectionId uint) int {
for i, collection := range collections {
if collection.ID == collectionId {
return i
diff --git a/internal/apitest/get_collection_test.go b/internal/apitest/get_collection_test.go
index c49faa5..c8a80b0 100644
--- a/internal/apitest/get_collection_test.go
+++ b/internal/apitest/get_collection_test.go
@@ -13,14 +13,14 @@ func TestGetCollection_Ok(t *testing.T) {
status, collection := testGetCollection(t, "1", "10", "0")
assert.Equal(t, http.StatusOK, status)
assert.Equal(t, "Littérature française", collection.Name)
- assert.Equal(t, 6, len(collection.Books))
+ assert.Equal(t, 6, len(collection.Items))
}
func TestGetCollection_Limit(t *testing.T) {
status, collection := testGetCollection(t, "2", "3", "0")
assert.Equal(t, http.StatusOK, status)
assert.Equal(t, "Nouvelles", collection.Name)
- assert.Equal(t, 3, len(collection.Books))
+ assert.Equal(t, 3, len(collection.Items))
assert.Equal(t, int64(4), collection.Count)
}
@@ -33,10 +33,17 @@ func TestGetCollection_Empty(t *testing.T) {
status, collection := testGetCollection(t, "4", "10", "0")
assert.Equal(t, http.StatusOK, status)
assert.Equal(t, "Empty", collection.Name)
- assert.Equal(t, 0, len(collection.Books))
+ assert.Equal(t, 0, len(collection.Items))
assert.Equal(t, int64(0), collection.Count)
}
+func TestGetCollection_Position(t *testing.T) {
+ status, collection := testGetCollection(t, "2", "3", "0")
+ assert.Equal(t, http.StatusOK, status)
+ assert.Equal(t, "Nouvelles", collection.Name)
+ assert.Equal(t, uint(3), collection.Items[2].Position)
+}
+
func testGetCollection(t *testing.T, id string, limit string, offset string) (int, dto.CollectionGet) {
return testutils.TestFetchModel[dto.CollectionGet](t, "/ws/collection/"+id, limit, offset)
}
diff --git a/internal/apitest/post_collection_addbook_test.go b/internal/apitest/post_collection_addbook_test.go
index 533abab..a63b48d 100644
--- a/internal/apitest/post_collection_addbook_test.go
+++ b/internal/apitest/post_collection_addbook_test.go
@@ -11,24 +11,36 @@ import (
"github.com/stretchr/testify/assert"
)
-func TestPostCollectionBookHandler_Ok(t *testing.T) {
+func TestPostCollectionBookHandler_AddOk(t *testing.T) {
payload :=
`{
"bookId": 9
}`
collectionId := "1"
- status := testPostCollectionBookHandler(t, collectionId, payload)
+ status := testPostCollectionBookHandler(collectionId, payload)
assert.Equal(t, http.StatusOK, status)
_, collection := testGetCollection(t, collectionId, "10", "0")
assert.Equal(t, int64(7), collection.Count)
}
+func TestPostCollectionBookHandler_BookOK(t *testing.T) {
+ payload :=
+ `{
+ "bookId": 7
+ }`
+ collectionId := "2"
+ status := testPostCollectionBookHandler(collectionId, payload)
+ assert.Equal(t, http.StatusOK, status)
+ _, collection := testGetCollection(t, collectionId, "10", "0")
+ assert.Equal(t, uint(7), collection.Items[0].Book.ID)
+}
+
func TestPostCollectionBookHandler_CollectionNotFound(t *testing.T) {
payload :=
`{
"bookId": 9
}`
- status := testPostCollectionBookHandler(t, "12", payload)
+ status := testPostCollectionBookHandler("12", payload)
assert.Equal(t, http.StatusNotFound, status)
}
@@ -37,7 +49,7 @@ func TestPostCollectionBookHandler_BookNotFound(t *testing.T) {
`{
"bookId": 14654
}`
- status := testPostCollectionBookHandler(t, "1", payload)
+ status := testPostCollectionBookHandler("1", payload)
assert.Equal(t, http.StatusNotFound, status)
}
@@ -46,11 +58,11 @@ func TestPostCollectionBookHandler_Unauthorized(t *testing.T) {
`{
"bookId": 9
}`
- status := testPostCollectionBookHandler(t, "3", payload)
+ status := testPostCollectionBookHandler("3", payload)
assert.Equal(t, http.StatusUnauthorized, status)
}
-func testPostCollectionBookHandler(t *testing.T, collectionId string, payload string) int {
+func testPostCollectionBookHandler(collectionId string, payload string) int {
router := testutils.TestSetup()
w := httptest.NewRecorder()
diff --git a/internal/db/init.go b/internal/db/init.go
index 05ae685..24ec742 100644
--- a/internal/db/init.go
+++ b/internal/db/init.go
@@ -23,6 +23,7 @@ func Initdb(databasePath string, demoDataPath string) *gorm.DB {
db.AutoMigrate(&model.UserBook{})
db.AutoMigrate(&model.StaticFile{})
db.AutoMigrate(&model.Collection{})
+ db.AutoMigrate(&model.CollectionItem{})
var book model.Book
queryResult := db.Limit(1).Find(&book)
if queryResult.RowsAffected == 0 && demoDataPath != "" {
diff --git a/internal/dto/out.go b/internal/dto/out.go
index bb48407..42cc1fc 100644
--- a/internal/dto/out.go
+++ b/internal/dto/out.go
@@ -45,23 +45,28 @@ type BookItemGet struct {
}
type CollectionGet struct {
- Name string `json:"name"`
- Count int64 `json:"count"`
- Books []BookItemGet `json:"books"`
-}
-
-type CollectionItemsGet struct {
- Count int64 `json:"count"`
- Collections []CollectionItemGet `json:"collections"`
+ Name string `json:"name"`
+ Count int64 `json:"count"`
+ Items []CollectionItemGet `json:"items"`
}
type CollectionItemGet struct {
- ID uint `json:"id"`
- Name string `json:"name"`
- Books []CollectionBookItemGet `json:"books"`
+ Position uint `json:"position"`
+ Book BookItemGet `json:"book"`
}
-type CollectionBookItemGet struct {
+type CollectionItemsGet struct {
+ Count int64 `json:"count"`
+ Collections []CollectionListItemGet `json:"collections"`
+}
+
+type CollectionListItemGet struct {
+ ID uint `json:"id"`
+ Name string `json:"name"`
+ Books []CollectionListBookItemGet `json:"books"`
+}
+
+type CollectionListBookItemGet struct {
ID uint `json:"id"`
Title string `json:"title"`
CoverPath string `json:"coverPath"`
diff --git a/internal/model/collection.go b/internal/model/collection.go
index 57f819d..741351a 100644
--- a/internal/model/collection.go
+++ b/internal/model/collection.go
@@ -7,5 +7,5 @@ type Collection struct {
Name string
User User
UserID uint
- Books []Book `gorm:"many2many:collection_books;"`
+ Items []CollectionItem
}
diff --git a/internal/model/collectionitem.go b/internal/model/collectionitem.go
new file mode 100644
index 0000000..091760d
--- /dev/null
+++ b/internal/model/collectionitem.go
@@ -0,0 +1,11 @@
+package model
+
+import "gorm.io/gorm"
+
+type CollectionItem struct {
+ gorm.Model
+ CollectionID uint
+ Position uint
+ Book Book
+ BookID uint
+}
diff --git a/internal/query/querycollections.go b/internal/query/querycollections.go
index 1f6f83f..7d6a51d 100644
--- a/internal/query/querycollections.go
+++ b/internal/query/querycollections.go
@@ -1,7 +1,6 @@
package query
import (
- "git.artlef.fr/bibliomane/internal/dto"
"git.artlef.fr/bibliomane/internal/model"
"gorm.io/gorm"
)
@@ -64,8 +63,8 @@ func fetchCollectionItemBook(db *gorm.DB, collectionId uint, limit int, offset i
func fetchCollectionItemBooksQuery(db *gorm.DB, collectionId uint) *gorm.DB {
query := db.Model(&model.Collection{})
query = query.Select("collections.id, collections.user_id, collections.name, books.id as book_id, books.title as book_title, " + selectStaticFilesPath())
- query = query.Joins("left join collection_books on (collection_books.collection_id = collections.id)")
- query = query.Joins("left join books on (books.id = collection_books.book_id)")
+ query = query.Joins("left join collection_items on (collection_items.collection_id = collections.id)")
+ query = query.Joins("left join books on (books.id = collection_items.book_id)")
query = joinStaticFiles(query)
query = query.Where("collections.id = ?", collectionId)
return query
@@ -81,14 +80,29 @@ func fetchCollections(db *gorm.DB, userId uint) *gorm.DB {
return db.Model(&model.Collection{}).Where("collections.user_id = ?", userId)
}
-func FetchCollectionBooks(db *gorm.DB, userId uint, collectionId uint, limit int, offset int) ([]dto.BookItemGet, error) {
- var books []dto.BookItemGet
+type CollectionItemQueryResult struct {
+ Position uint
+ ID uint
+ Title string
+ Author string
+ Description string
+ InventaireID string
+ IsInventaireEdition bool
+ Rating int
+ Read bool
+ StartReadDate string
+ WantRead bool
+ CoverPath string
+}
+
+func FetchCollectionItems(db *gorm.DB, userId uint, collectionId uint, limit int, offset int) ([]CollectionItemQueryResult, error) {
+ var collectionitems []CollectionItemQueryResult
query := fetchCollectionBooksQuery(db, userId, collectionId)
query = query.Limit(limit)
query = query.Offset(offset)
- query = query.Order("books.id DESC")
- res := query.Find(&books)
- return books, res.Error
+ query = query.Order("collection_items.position")
+ res := query.Find(&collectionitems)
+ return collectionitems, res.Error
}
func FetchCollectionBooksCount(db *gorm.DB, userId uint, collectionId uint) (int64, error) {
@@ -98,8 +112,14 @@ func FetchCollectionBooksCount(db *gorm.DB, userId uint, collectionId uint) (int
}
func fetchCollectionBooksQuery(db *gorm.DB, userId uint, collectionId uint) *gorm.DB {
- query := fetchBookQueryBuilder(db, userId)
- query = query.Joins("left join collection_books on (collection_books.book_id = books.id)")
- query = query.Where("collection_books.collection_id = ?", collectionId)
+ query := db.Model(&model.CollectionItem{})
+ query = query.Select("collection_items.position, " + selectBookItem())
+ query = query.Joins("left join collections on (collection_items.collection_id = collections.id)")
+ query = query.Joins("left join books on (books.id = collection_items.book_id)")
+ query = joinAuthors(query)
+ query = query.Joins("left join user_books on (user_books.book_id = books.id and user_books.user_id = ?)", userId)
+ query = joinStaticFiles(query)
+ query = query.Order("collection_items.position")
+ query = query.Where("collections.id = ?", collectionId)
return query
}
diff --git a/internal/routes/collectionaddbookpost.go b/internal/routes/collectionaddbookpost.go
index f93d66d..a656b11 100644
--- a/internal/routes/collectionaddbookpost.go
+++ b/internal/routes/collectionaddbookpost.go
@@ -56,7 +56,7 @@ func PostCollectionBookHandler(ac appcontext.AppContext) {
return
}
- collection.Books = append(collection.Books, book)
- ac.Db.Save(&collection)
+ item := model.CollectionItem{Position: 0, BookID: book.ID, CollectionID: collection.ID}
+ ac.Db.Save(&item)
ac.C.String(http.StatusOK, "Success")
}
diff --git a/internal/routes/collectionget.go b/internal/routes/collectionget.go
index 2084681..ce86dc6 100644
--- a/internal/routes/collectionget.go
+++ b/internal/routes/collectionget.go
@@ -5,6 +5,7 @@ import (
"net/http"
"strconv"
+ "git.artlef.fr/bibliomane/internal/adapter"
"git.artlef.fr/bibliomane/internal/appcontext"
"git.artlef.fr/bibliomane/internal/dto"
"git.artlef.fr/bibliomane/internal/i18nresource"
@@ -50,12 +51,13 @@ func GetCollectionHandler(ac appcontext.AppContext) {
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
return
}
- books, err := query.FetchCollectionBooks(ac.Db, user.ID, uint(collectionId), limit, offset)
+ itemsQueryResult, err := query.FetchCollectionItems(ac.Db, user.ID, uint(collectionId), limit, offset)
if err != nil {
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)
return
}
- collection.Books = books
+ items := adapter.CollectionItemsQueryToDto(itemsQueryResult)
+ collection.Items = items
count, err := query.FetchCollectionBooksCount(ac.Db, user.ID, uint(collectionId))
if err != nil {
myvalidator.ReturnErrorsAsJsonResponse(&ac, err)