added save and load for category

marked some image functions internal
This commit is contained in:
Philipp Häfelfinger 2019-04-06 23:23:43 +02:00
parent 402ac902a5
commit 6acd3f8a55
2 changed files with 146 additions and 30 deletions

View File

@ -110,7 +110,7 @@ func (d *LocalDataStore) ImageMetadata(fullImagePath string) (ImageMetaData, err
defer rows.Close() defer rows.Close()
if rows.Next() { if rows.Next() {
err = ReadImageMetadataFromRow(rows, &img) err = readImageMetadataFromRow(rows, &img)
if err != nil { if err != nil {
return img, err return img, err
} }
@ -140,7 +140,7 @@ func (d *LocalDataStore) ImageMetadataAll() ([]ImageMetaData, error) {
images := []ImageMetaData{} images := []ImageMetaData{}
for rows.Next() { for rows.Next() {
img := &ImageMetaData{} img := &ImageMetaData{}
err = ReadImageMetadataFromRow(rows, img) err = readImageMetadataFromRow(rows, img)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -169,7 +169,7 @@ func (d *LocalDataStore) ImageMetadataToDelete() ([]ImageMetaData, error) {
images := []ImageMetaData{} images := []ImageMetaData{}
for rows.Next() { for rows.Next() {
img := &ImageMetaData{} img := &ImageMetaData{}
err = ReadImageMetadataFromRow(rows, img) err = readImageMetadataFromRow(rows, img)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -198,7 +198,7 @@ func (d *LocalDataStore) ImageMetadataToUpload() ([]ImageMetaData, error) {
images := []ImageMetaData{} images := []ImageMetaData{}
for rows.Next() { for rows.Next() {
img := &ImageMetaData{} img := &ImageMetaData{}
err = ReadImageMetadataFromRow(rows, img) err = readImageMetadataFromRow(rows, img)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -209,11 +209,6 @@ func (d *LocalDataStore) ImageMetadataToUpload() ([]ImageMetaData, error) {
return images, err 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 { func (d *LocalDataStore) SaveImageMetadata(img ImageMetaData) error {
logrus.Tracef("Saving imagemetadata: %s", img.String()) logrus.Tracef("Saving imagemetadata: %s", img.String())
db, err := d.openDatabase() db, err := d.openDatabase()
@ -311,7 +306,35 @@ func (d *LocalDataStore) DeleteMarkedImages() error {
} }
func (d *LocalDataStore) SaveCategory(category CategoryData) 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) { 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) { 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) { func (d *LocalDataStore) GetCategoriesToCreate() ([]CategoryData, error) {
panic("implement me") 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) { func (d *LocalDataStore) openDatabase() (*sql.DB, error) {
db, err := sql.Open("sqlite3", d.connectionString) db, err := sql.Open("sqlite3", d.connectionString)
if err != nil { if err != nil {
@ -393,6 +437,20 @@ func (d *LocalDataStore) createTablesIfNeeded(db *sql.DB) error {
return nil 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 { 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 = ?") stmt, err := tx.Prepare("UPDATE image SET piwigoId = ?, fullImagePath = ?, fileName = ?, md5sum = ?, lastChanged = ?, categoryPath = ?, categoryPiwigoId = ?, uploadRequired = ?, deleteRequired = ? WHERE imageId = ?")
if err != nil { 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) _, 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 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
}

View File

@ -34,14 +34,14 @@ func Test_save_and_load_metadata(t *testing.T) {
img.ImageId = 1 img.ImageId = 1
imgLoad := loadMetadataShouldNotFail("insert", dataStore, filePath, t) imgLoad := loadMetadataShouldNotFail("insert", dataStore, filePath, t)
EnsureMetadataAreEqual("insert", img, imgLoad, t) ensureMetadataAreEqual("insert", img, imgLoad, t)
// updated the image again // updated the image again
img.Md5Sum = "123456" img.Md5Sum = "123456"
saveImageShouldNotFail("update", dataStore, img, t) saveImageShouldNotFail("update", dataStore, img, t)
imgLoad = loadMetadataShouldNotFail("update", dataStore, filePath, 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) { 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] imgLoad := images[0]
EnsureMetadataAreEqual("allimages", img1, imgLoad, t) ensureMetadataAreEqual("allimages", img1, imgLoad, t)
} }
func Test_save_and_query_for_upload_records(t *testing.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] 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] 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) { 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] imgLoad := images[0]
EnsureMetadataAreEqual("todelete", img1, imgLoad, t) ensureMetadataAreEqual("todelete", img1, imgLoad, t)
} }
func Test_load_metadata_not_found(t *testing.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) 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) { 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) 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) { 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() images, err := dataStore.ImageMetadataAll()
if err != nil { 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 { 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) { func saveImageShouldNotFail(action string, dataStore *LocalDataStore, img ImageMetaData, t *testing.T) {
err := dataStore.SaveImageMetadata(img) err := dataStore.SaveImageMetadata(img)
if err != nil { 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 { func loadMetadataShouldNotFail(action string, dataStore *LocalDataStore, filePath string, t *testing.T) ImageMetaData {
imgLoad, err := dataStore.ImageMetadata(filePath) imgLoad, err := dataStore.ImageMetadata(filePath)
if err != nil { if err != nil {
@ -303,13 +328,23 @@ func loadMetadataShouldNotFail(action string, dataStore *LocalDataStore, filePat
return imgLoad 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 // check if both instances serialize to the same string representation
if img.String() != imgLoad.String() { if img.String() != imgLoad.String() {
t.Errorf("%s: Invalid image loaded! expected (ignore ImageId) %s but got %s", action, 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 { func getExampleImageMetadata(filePath string) ImageMetaData {
return ImageMetaData{ return ImageMetaData{
FullImagePath: filePath, FullImagePath: filePath,