From 6acd3f8a55e01411092da9373437d0b269a58f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=A4felfinger?= Date: Sat, 6 Apr 2019 23:23:43 +0200 Subject: [PATCH] added save and load for category marked some image functions internal --- internal/pkg/datastore/datastore.go | 121 +++++++++++++++++++---- internal/pkg/datastore/datastore_test.go | 55 +++++++++-- 2 files changed, 146 insertions(+), 30 deletions(-) diff --git a/internal/pkg/datastore/datastore.go b/internal/pkg/datastore/datastore.go index 16687e5..e6f4352 100644 --- a/internal/pkg/datastore/datastore.go +++ b/internal/pkg/datastore/datastore.go @@ -110,7 +110,7 @@ func (d *LocalDataStore) ImageMetadata(fullImagePath string) (ImageMetaData, err defer rows.Close() if rows.Next() { - err = ReadImageMetadataFromRow(rows, &img) + err = readImageMetadataFromRow(rows, &img) if err != nil { return img, err } @@ -140,7 +140,7 @@ func (d *LocalDataStore) ImageMetadataAll() ([]ImageMetaData, error) { images := []ImageMetaData{} for rows.Next() { img := &ImageMetaData{} - err = ReadImageMetadataFromRow(rows, img) + err = readImageMetadataFromRow(rows, img) if err != nil { return nil, err } @@ -169,7 +169,7 @@ func (d *LocalDataStore) ImageMetadataToDelete() ([]ImageMetaData, error) { images := []ImageMetaData{} for rows.Next() { img := &ImageMetaData{} - err = ReadImageMetadataFromRow(rows, img) + err = readImageMetadataFromRow(rows, img) if err != nil { return nil, err } @@ -198,7 +198,7 @@ func (d *LocalDataStore) ImageMetadataToUpload() ([]ImageMetaData, error) { images := []ImageMetaData{} for rows.Next() { img := &ImageMetaData{} - err = ReadImageMetadataFromRow(rows, img) + err = readImageMetadataFromRow(rows, img) if err != nil { return nil, err } @@ -209,11 +209,6 @@ func (d *LocalDataStore) ImageMetadataToUpload() ([]ImageMetaData, error) { return images, err } -func ReadImageMetadataFromRow(rows *sql.Rows, img *ImageMetaData) error { - err := rows.Scan(&img.ImageId, &img.PiwigoId, &img.FullImagePath, &img.Filename, &img.Md5Sum, &img.LastChange, &img.CategoryPath, &img.CategoryPiwigoId, &img.UploadRequired, &img.DeleteRequired) - return err -} - func (d *LocalDataStore) SaveImageMetadata(img ImageMetaData) error { logrus.Tracef("Saving imagemetadata: %s", img.String()) db, err := d.openDatabase() @@ -311,7 +306,35 @@ func (d *LocalDataStore) DeleteMarkedImages() error { } func (d *LocalDataStore) SaveCategory(category CategoryData) error { - panic("implement me") + logrus.Tracef("Saving category: %s", category.String()) + db, err := d.openDatabase() + if err != nil { + return err + } + defer db.Close() + + tx, err := db.Begin() + if err != nil { + return err + } + + if category.CategoryId <= 0 { + err = d.insertCategoryData(tx, category) + } else { + err = d.updateCategoryData(tx, category) + } + + if err != nil { + logrus.Errorf("Rolling back transaction for category of %s", category.Key) + errTx := tx.Rollback() + if errTx != nil { + logrus.Errorf("Rollback of transaction for category of %s failed!", category.Key) + } + return err + } + + logrus.Tracef("Committing category for image %s", category.String()) + return tx.Commit() } func (d *LocalDataStore) GetCategoryByPiwigoId(id int) (CategoryData, error) { @@ -319,22 +342,43 @@ func (d *LocalDataStore) GetCategoryByPiwigoId(id int) (CategoryData, error) { } func (d *LocalDataStore) GetCategoryByKey(key string) (CategoryData, error) { - panic("implement me") + logrus.Tracef("Query category %s", key) + cat := CategoryData{} + + db, err := d.openDatabase() + if err != nil { + return cat, err + } + defer db.Close() + + stmt, err := db.Prepare("SELECT categoryId, piwigoId, piwigoParentId, name, key FROM category WHERE key = ?") + if err != nil { + return cat, err + } + + rows, err := stmt.Query(key) + if err != nil { + return cat, err + } + defer rows.Close() + + if rows.Next() { + err = readCategoryFromRow(rows, &cat) + if err != nil { + return cat, err + } + } else { + return cat, ErrorRecordNotFound + } + err = rows.Err() + + return cat, err } func (d *LocalDataStore) GetCategoriesToCreate() ([]CategoryData, error) { panic("implement me") } -func (d *LocalDataStore) insertImageMetaData(tx *sql.Tx, data ImageMetaData) error { - stmt, err := tx.Prepare("INSERT INTO image (piwigoId, fullImagePath, fileName, md5sum, lastChanged, categoryPath, categoryPiwigoId, uploadRequired, deleteRequired) VALUES (?,?,?,?,?,?,?,?,?)") - if err != nil { - return err - } - _, err = stmt.Exec(data.PiwigoId, data.FullImagePath, data.Filename, data.Md5Sum, data.LastChange, data.CategoryPath, data.CategoryPiwigoId, data.UploadRequired, data.DeleteRequired) - return err -} - func (d *LocalDataStore) openDatabase() (*sql.DB, error) { db, err := sql.Open("sqlite3", d.connectionString) if err != nil { @@ -393,6 +437,20 @@ func (d *LocalDataStore) createTablesIfNeeded(db *sql.DB) error { return nil } +func readImageMetadataFromRow(rows *sql.Rows, img *ImageMetaData) error { + err := rows.Scan(&img.ImageId, &img.PiwigoId, &img.FullImagePath, &img.Filename, &img.Md5Sum, &img.LastChange, &img.CategoryPath, &img.CategoryPiwigoId, &img.UploadRequired, &img.DeleteRequired) + return err +} + +func (d *LocalDataStore) insertImageMetaData(tx *sql.Tx, data ImageMetaData) error { + stmt, err := tx.Prepare("INSERT INTO image (piwigoId, fullImagePath, fileName, md5sum, lastChanged, categoryPath, categoryPiwigoId, uploadRequired, deleteRequired) VALUES (?,?,?,?,?,?,?,?,?)") + if err != nil { + return err + } + _, err = stmt.Exec(data.PiwigoId, data.FullImagePath, data.Filename, data.Md5Sum, data.LastChange, data.CategoryPath, data.CategoryPiwigoId, data.UploadRequired, data.DeleteRequired) + return err +} + func (d *LocalDataStore) updateImageMetaData(tx *sql.Tx, data ImageMetaData) error { stmt, err := tx.Prepare("UPDATE image SET piwigoId = ?, fullImagePath = ?, fileName = ?, md5sum = ?, lastChanged = ?, categoryPath = ?, categoryPiwigoId = ?, uploadRequired = ?, deleteRequired = ? WHERE imageId = ?") if err != nil { @@ -401,3 +459,26 @@ func (d *LocalDataStore) updateImageMetaData(tx *sql.Tx, data ImageMetaData) err _, err = stmt.Exec(data.PiwigoId, data.FullImagePath, data.Filename, data.Md5Sum, data.LastChange, data.CategoryPath, data.CategoryPiwigoId, data.UploadRequired, data.DeleteRequired, data.ImageId) return err } + +func readCategoryFromRow(rows *sql.Rows, cat *CategoryData) error { + err := rows.Scan(&cat.CategoryId, &cat.PiwigoId, &cat.PiwigoParentId, &cat.Name, &cat.Key) + return err +} + +func (d *LocalDataStore) updateCategoryData(tx *sql.Tx, data CategoryData) error { + stmt, err := tx.Prepare("UPDATE category SET piwigoId = ?, piwigoParentId = ?, name = ?, key = ? WHERE categoryId = ?") + if err != nil { + return err + } + _, err = stmt.Exec(data.PiwigoId, data.PiwigoParentId, data.Name, data.Key, data.CategoryId) + return err +} + +func (d *LocalDataStore) insertCategoryData(tx *sql.Tx, data CategoryData) error { + stmt, err := tx.Prepare("INSERT INTO category (piwigoId, piwigoParentId, name, key) VALUES (?,?,?,?)") + if err != nil { + return err + } + _, err = stmt.Exec(data.PiwigoId, data.PiwigoParentId, data.Name, data.Key) + return err +} diff --git a/internal/pkg/datastore/datastore_test.go b/internal/pkg/datastore/datastore_test.go index cbf3984..f3574d4 100644 --- a/internal/pkg/datastore/datastore_test.go +++ b/internal/pkg/datastore/datastore_test.go @@ -34,14 +34,14 @@ func Test_save_and_load_metadata(t *testing.T) { img.ImageId = 1 imgLoad := loadMetadataShouldNotFail("insert", dataStore, filePath, t) - EnsureMetadataAreEqual("insert", img, imgLoad, t) + ensureMetadataAreEqual("insert", img, imgLoad, t) // updated the image again img.Md5Sum = "123456" saveImageShouldNotFail("update", dataStore, img, t) imgLoad = loadMetadataShouldNotFail("update", dataStore, filePath, t) - EnsureMetadataAreEqual("update", img, imgLoad, t) + ensureMetadataAreEqual("update", img, imgLoad, t) } func Test_save_and_query_for_all_entries(t *testing.T) { @@ -72,7 +72,7 @@ func Test_save_and_query_for_all_entries(t *testing.T) { } imgLoad := images[0] - EnsureMetadataAreEqual("allimages", img1, imgLoad, t) + ensureMetadataAreEqual("allimages", img1, imgLoad, t) } func Test_save_and_query_for_upload_records(t *testing.T) { @@ -97,7 +97,7 @@ func Test_save_and_query_for_upload_records(t *testing.T) { } imgLoad := images[0] - EnsureMetadataAreEqual("toupload", img, imgLoad, t) + ensureMetadataAreEqual("toupload", img, imgLoad, t) } @@ -133,7 +133,7 @@ func Test_save_and_query_for_upload_records_do_not_contain_images_to_delete(t *t } imgLoad := images[0] - EnsureMetadataAreEqual("toupload", img1, imgLoad, t) + ensureMetadataAreEqual("toupload", img1, imgLoad, t) } func Test_save_and_query_for_deleted_records_do_contain_images(t *testing.T) { @@ -164,7 +164,7 @@ func Test_save_and_query_for_deleted_records_do_contain_images(t *testing.T) { } imgLoad := images[0] - EnsureMetadataAreEqual("todelete", img1, imgLoad, t) + ensureMetadataAreEqual("todelete", img1, imgLoad, t) } func Test_load_metadata_not_found(t *testing.T) { @@ -228,7 +228,7 @@ func Test_update_piwigoId_by_checksum(t *testing.T) { } imgLoad := loadMetadataShouldNotFail("update", dataStore, filePath, t) - EnsureMetadataAreEqual("SavePiwigoIdAndUpdateUploadFlag", img, imgLoad, t) + ensureMetadataAreEqual("SavePiwigoIdAndUpdateUploadFlag", img, imgLoad, t) } func Test_update_piwigoId_by_checksum_found_no_image(t *testing.T) { @@ -252,7 +252,7 @@ func Test_update_piwigoId_by_checksum_found_no_image(t *testing.T) { } imgLoad := loadMetadataShouldNotFail("update", dataStore, filePath, t) - EnsureMetadataAreEqual("SavePiwigoIdAndUpdateUploadFlag", img, imgLoad, t) + ensureMetadataAreEqual("SavePiwigoIdAndUpdateUploadFlag", img, imgLoad, t) } func Test_deleteMarkedImages_should_remove_records(t *testing.T) { @@ -280,7 +280,7 @@ func Test_deleteMarkedImages_should_remove_records(t *testing.T) { images, err := dataStore.ImageMetadataAll() if err != nil { - t.Fatalf("Could not query images to upload! %s", err) + t.Fatalf("Could not query images! %s", err) } if len(images) != 1 { @@ -288,6 +288,24 @@ func Test_deleteMarkedImages_should_remove_records(t *testing.T) { } } +func Test_saveCategory_should_store_records(t *testing.T) { + if !dbinitOk { + t.Skip("Skipping test as TestDataStoreInitialize failed!") + } + dataStore := setupDatabase(t) + defer cleanupDatabase(t) + + category := getExampleCategoryData("2019") + + saveCategoryShouldNotFail("addcategory", dataStore, category, t) + category.CategoryId = 1 + + _, err := dataStore.GetCategoryByKey(category.Key) + if err != nil { + t.Fatalf("Could not query category! %s", err) + } +} + func saveImageShouldNotFail(action string, dataStore *LocalDataStore, img ImageMetaData, t *testing.T) { err := dataStore.SaveImageMetadata(img) if err != nil { @@ -295,6 +313,13 @@ func saveImageShouldNotFail(action string, dataStore *LocalDataStore, img ImageM } } +func saveCategoryShouldNotFail(action string, dataStore *LocalDataStore, cat CategoryData, t *testing.T) { + err := dataStore.SaveCategory(cat) + if err != nil { + t.Errorf("%s: Could not save category: %s", action, err) + } +} + func loadMetadataShouldNotFail(action string, dataStore *LocalDataStore, filePath string, t *testing.T) ImageMetaData { imgLoad, err := dataStore.ImageMetadata(filePath) if err != nil { @@ -303,13 +328,23 @@ func loadMetadataShouldNotFail(action string, dataStore *LocalDataStore, filePat return imgLoad } -func EnsureMetadataAreEqual(action string, img ImageMetaData, imgLoad ImageMetaData, t *testing.T) { +func ensureMetadataAreEqual(action string, img ImageMetaData, imgLoad ImageMetaData, t *testing.T) { // check if both instances serialize to the same string representation if img.String() != imgLoad.String() { t.Errorf("%s: Invalid image loaded! expected (ignore ImageId) %s but got %s", action, img.String(), imgLoad.String()) } } +func getExampleCategoryData(key string) CategoryData { + return CategoryData{ + CategoryId: 0, + PiwigoId: 1, + Key: key, + Name: key, + PiwigoParentId: 0, + } +} + func getExampleImageMetadata(filePath string) ImageMetaData { return ImageMetaData{ FullImagePath: filePath,