diff --git a/backend/cmd/analogdb/main.go b/backend/cmd/analogdb/main.go index fabf913..3fe7672 100644 --- a/backend/cmd/analogdb/main.go +++ b/backend/cmd/analogdb/main.go @@ -40,9 +40,9 @@ func main() { fmt.Fprintln(os.Stderr, err) os.Exit(1) } - logger.Info().Str("App", cfg.App.Name).Str("Version", cfg.App.Version).Msg("Initializing application") + logger.Info().Str("App", cfg.App.Name).Str("Version", cfg.App.Version).Str("env", cfg.App.Env).Str("loglevel", cfg.Log.Level).Msg("Initializing application") - if webhookURL := cfg.Log.WebhookURL; webhookURL != "" { + if webhookURL := cfg.Log.WebhookURL; webhookURL != "" && cfg.App.Env != "debug" { logger = logger.WithSlackNotifier(webhookURL) } @@ -50,7 +50,7 @@ func main() { db := postgres.NewDB(cfg.DB.URL, dbLogger) if err := db.Open(); err != nil { err = fmt.Errorf("Failed to startup datebase: %w", err) - logger.Err(err).Msg("Fatal error, exiting") + logger.Error().Err(err).Msg("Fatal error, exiting") os.Exit(1) } @@ -59,14 +59,14 @@ func main() { dbVec := weaviate.NewDB(cfg.VectorDB.Host, cfg.VectorDB.Scheme, dbVecLogger) if err := dbVec.Open(); err != nil { err = fmt.Errorf("Failed to startup vector datebase: %w", err) - logger.Err(err).Msg("Fatal error, exiting") + logger.Error().Err(err).Msg("Fatal error, exiting") os.Exit(1) } // run weaviate migrations if needed // creates the schema if it does not exist if err := dbVec.Migrate(ctx); err != nil { err = fmt.Errorf("Failed to migrate vector datebase: %w", err) - logger.Err(err).Msg("Fatal error, exiting") + logger.Error().Err(err).Msg("Fatal error, exiting") os.Exit(1) } @@ -81,7 +81,7 @@ func main() { server.SimilarityService = weaviate.NewSimilarityService(dbVec, postService) if err := server.Run(); err != nil { err = fmt.Errorf("Failed to start http server: %w", err) - logger.Err(err).Msg("Fatal error, exiting") + logger.Error().Err(err).Msg("Fatal error, exiting") os.Exit(1) } @@ -90,13 +90,19 @@ func main() { if err := server.Close(); err != nil { err = fmt.Errorf("Failed to shutdown http server: %w", err) - logger.Err(err).Msg("Fatal error, exiting") + logger.Error().Err(err).Msg("Fatal error, exiting") os.Exit(1) } if err := db.Close(); err != nil { err = fmt.Errorf("Failed to shutdown DB: %w", err) - logger.Err(err).Msg("Fatal error, exiting") + logger.Error().Err(err).Msg("Fatal error, exiting") + os.Exit(1) + } + + if err := dbVec.Close(); err != nil { + err = fmt.Errorf("Failed to shutdown vector DB: %w", err) + logger.Error().Err(err).Msg("Fatal error, exiting") os.Exit(1) } } diff --git a/backend/postgres/post.go b/backend/postgres/post.go index 3ee06d4..3ce575b 100644 --- a/backend/postgres/post.go +++ b/backend/postgres/post.go @@ -84,7 +84,7 @@ func (s *PostService) CreatePost(ctx context.Context, post *analogdb.CreatePost) return nil, err } defer tx.Rollback() - createdPost, err := createPost(ctx, tx, post) + createdPost, err := s.db.createPost(ctx, tx, post) if err != nil { return nil, err } @@ -97,7 +97,7 @@ func (s *PostService) FindPosts(ctx context.Context, filter *analogdb.PostFilter return nil, 0, err } defer tx.Rollback() - return findPosts(ctx, tx, filter) + return s.db.findPosts(ctx, tx, filter) } func (s *PostService) FindPostByID(ctx context.Context, id int) (*analogdb.Post, error) { @@ -107,7 +107,7 @@ func (s *PostService) FindPostByID(ctx context.Context, id int) (*analogdb.Post, } defer tx.Rollback() ids := []int{id} - posts, _, err := findPosts(ctx, tx, &analogdb.PostFilter{IDs: &ids}) + posts, _, err := s.db.findPosts(ctx, tx, &analogdb.PostFilter{IDs: &ids}) if err != nil { return nil, err } else if len(posts) == 0 { @@ -122,7 +122,7 @@ func (s *PostService) PatchPost(ctx context.Context, patch *analogdb.PatchPost, return err } defer tx.Rollback() - err = patchPost(ctx, tx, patch, id) + err = s.db.patchPost(ctx, tx, patch, id) if err != nil { return &analogdb.Error{Code: analogdb.ERRINTERNAL, Message: err.Error()} } @@ -135,7 +135,7 @@ func (s *PostService) DeletePost(ctx context.Context, id int) error { return err } defer tx.Rollback() - err = deletePost(ctx, tx, id) + err = s.db.deletePost(ctx, tx, id) if err != nil { return &analogdb.Error{Code: analogdb.ERRINTERNAL, Message: err.Error()} } @@ -148,7 +148,7 @@ func (s *PostService) AllPostIDs(ctx context.Context) ([]int, error) { return nil, err } defer tx.Rollback() - ids, err := allPostIDs(ctx, tx) + ids, err := s.db.allPostIDs(ctx, tx) if err != nil { return nil, err @@ -158,9 +158,13 @@ func (s *PostService) AllPostIDs(ctx context.Context) ([]int, error) { } // insertPost inserts a post into the DB and returns the post's ID -func insertPost(ctx context.Context, tx *sql.Tx, post *analogdb.CreatePost) (*int64, error) { +func (db *DB) insertPost(ctx context.Context, tx *sql.Tx, post *analogdb.CreatePost) (*int64, error) { + + db.logger.Debug().Msg("Starting insert post") + create, err := createPostToRawPostCreate(post) if err != nil { + db.logger.Error().Err(err).Msg("Failed to insert post") return nil, err } @@ -178,6 +182,7 @@ func insertPost(ctx context.Context, tx *sql.Tx, post *analogdb.CreatePost) (*in stmt, err := tx.PrepareContext(ctx, query) if err != nil { + db.logger.Error().Err(err).Int64("postID", id).Msg("Failed to insert post") return nil, err } @@ -222,14 +227,19 @@ func insertPost(ctx context.Context, tx *sql.Tx, post *analogdb.CreatePost) (*in create.c5_percent).Scan(&id) if err != nil { + db.logger.Error().Err(err).Int64("postID", id).Msg("Failed to insert post") return nil, err } + db.logger.Info().Int64("postID", id).Msg("Finished inserting post") + return &id, nil } // insertKeywords inserts a post's keywords into the DB -func insertKeywords(ctx context.Context, tx *sql.Tx, keywords []analogdb.Keyword, postID int64) error { +func (db *DB) insertKeywords(ctx context.Context, tx *sql.Tx, keywords []analogdb.Keyword, postID int64) error { + + db.logger.Debug().Int64("postID", postID).Msg("Starting insert keywords") first := 1 second := 2 @@ -256,6 +266,7 @@ func insertKeywords(ctx context.Context, tx *sql.Tx, keywords []analogdb.Keyword stmt, err := tx.PrepareContext(ctx, query) if err != nil { + db.logger.Error().Err(err).Int64("postID", postID).Msg("Failed to insert keywords") return err } @@ -264,14 +275,19 @@ func insertKeywords(ctx context.Context, tx *sql.Tx, keywords []analogdb.Keyword _, err = stmt.ExecContext(ctx, vals...) if err != nil { + db.logger.Error().Err(err).Int64("postID", postID).Msg("Failed to insert keywords") return err } + db.logger.Info().Int64("postID", postID).Msg("Finished inserting keywords") + return nil } // deleteKeywords deletes all keywords for a given post -func deleteKeywords(ctx context.Context, tx *sql.Tx, postID int64) error { +func (db *DB) deleteKeywords(ctx context.Context, tx *sql.Tx, postID int64) error { + + db.logger.Debug().Int64("postID", postID).Msg("Starting delete keywords") query := "DELETE FROM keywords WHERE post_id = $1" @@ -279,21 +295,26 @@ func deleteKeywords(ctx context.Context, tx *sql.Tx, postID int64) error { rows, err := tx.QueryContext(ctx, query, postID) defer rows.Close() if err != nil { + db.logger.Error().Err(err).Int64("postID", postID).Msg("Failed to delete keywords") return err } + + db.logger.Info().Int64("postID", postID).Msg("Finished deleting keywords") return nil } -func createPost(ctx context.Context, tx *sql.Tx, post *analogdb.CreatePost) (*analogdb.Post, error) { +func (db *DB) createPost(ctx context.Context, tx *sql.Tx, post *analogdb.CreatePost) (*analogdb.Post, error) { + + db.logger.Debug().Msg("Starting create post") - id, err := insertPost(ctx, tx, post) + id, err := db.insertPost(ctx, tx, post) if err != nil { return nil, err } // insert keywords if they are provided if len(post.Keywords) != 0 { - err = insertKeywords(ctx, tx, post.Keywords, *id) + err = db.insertKeywords(ctx, tx, post.Keywords, *id) if err != nil { return nil, err } @@ -302,6 +323,7 @@ func createPost(ctx context.Context, tx *sql.Tx, post *analogdb.CreatePost) (*an // commit transaction if both inserts are ok err = tx.Commit() if err != nil { + db.logger.Error().Err(err).Int64("postID", *id).Msg("Failed to create post") return nil, err } @@ -324,13 +346,19 @@ func createPost(ctx context.Context, tx *sql.Tx, post *analogdb.CreatePost) (*an Id: int(*id), DisplayPost: displayPost, } + + db.logger.Info().Int64("postID", *id).Msg("Finished creating post") + return createdPost, nil } // findPosts is the general function responsible for handling all queries -func findPosts(ctx context.Context, tx *sql.Tx, filter *analogdb.PostFilter) ([]*analogdb.Post, int, error) { +func (db *DB) findPosts(ctx context.Context, tx *sql.Tx, filter *analogdb.PostFilter) ([]*analogdb.Post, int, error) { + + db.logger.Debug().Msg("Starting find posts") if err := validateFilter(filter); err != nil { + db.logger.Error().Err(err).Msg("Failed to find posts") return nil, 0, err } @@ -385,6 +413,7 @@ func findPosts(ctx context.Context, tx *sql.Tx, filter *analogdb.PostFilter) ([] rows, err := tx.QueryContext(ctx, query, args...) if err != nil { + db.logger.Error().Err(err).Msg("Failed to find posts") return nil, 0, err } defer rows.Close() @@ -395,6 +424,7 @@ func findPosts(ctx context.Context, tx *sql.Tx, filter *analogdb.PostFilter) ([] for rows.Next() { p, count, err = scanRowToRawPostCount(rows) if err != nil { + db.logger.Error().Err(err).Msg("Failed to find posts") return nil, 0, err } post, err := rawPostToPost(*p) @@ -403,6 +433,7 @@ func findPosts(ctx context.Context, tx *sql.Tx, filter *analogdb.PostFilter) ([] stripAuthorPrefix(post) if err != nil { + db.logger.Error().Err(err).Msg("Failed to find posts") return nil, 0, err } posts = append(posts, post) @@ -411,71 +442,94 @@ func findPosts(ctx context.Context, tx *sql.Tx, filter *analogdb.PostFilter) ([] err = tx.Commit() if err != nil { + db.logger.Error().Err(err).Msg("Failed to find posts") return nil, 0, err } + db.logger.Info().Msg("Finished finding posts") + return posts, count, nil } -func patchPost(ctx context.Context, tx *sql.Tx, patch *analogdb.PatchPost, id int) error { +func (db *DB) patchPost(ctx context.Context, tx *sql.Tx, patch *analogdb.PatchPost, id int) error { + + db.logger.Debug().Int("postID", id).Msg("Starting patch post") hasPatchFields := false // if the patch includes updates for the post if patch.Nsfw != nil || patch.Sprocket != nil || patch.Grayscale != nil || patch.Score != nil || patch.Colors != nil { hasPatchFields = true - if err := updatePost(ctx, tx, patch, id); err != nil { + if err := db.updatePost(ctx, tx, patch, id); err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to patch post") return err } } // if the patch includes updates for keywords if patch.Keywords != nil { hasPatchFields = true - if err := updateKeywords(ctx, tx, *patch.Keywords, id); err != nil { + if err := db.updateKeywords(ctx, tx, *patch.Keywords, id); err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to patch post") return err } } if !hasPatchFields { - return errors.New("must include patch parameters") + err := errors.New("must include patch parameters") + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to patch post") + return err } // always insert the updated timestamp - if err := insertPostUpdateTimes(ctx, tx, patch, id); err != nil { + if err := db.insertPostUpdateTimes(ctx, tx, patch, id); err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to patch post") return err } err := tx.Commit() if err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to patch post") return err } + db.logger.Info().Int("postID", id).Msg("Finished patching post") + return nil } -func updateKeywords(ctx context.Context, tx *sql.Tx, keywords []analogdb.Keyword, id int) error { +func (db *DB) updateKeywords(ctx context.Context, tx *sql.Tx, keywords []analogdb.Keyword, id int) error { + + db.logger.Debug().Int("postID", id).Msg("Starting update keywords") // first delete all keywords associated with post - if err := deleteKeywords(ctx, tx, int64(id)); err != nil { + if err := db.deleteKeywords(ctx, tx, int64(id)); err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to update keywords") return err } // if we have no keywords to insert, just return if len(keywords) == 0 { + db.logger.Info().Int("postID", id).Msg("Finished updating keywords (dropped all keywords)") return nil } // then insert all new keywords - if err := insertKeywords(ctx, tx, keywords, int64(id)); err != nil { + if err := db.insertKeywords(ctx, tx, keywords, int64(id)); err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to update keywords") return err } + + db.logger.Info().Int("postID", id).Msg("Finished updating keywords") return nil } -func updatePost(ctx context.Context, tx *sql.Tx, patch *analogdb.PatchPost, id int) error { +func (db *DB) updatePost(ctx context.Context, tx *sql.Tx, patch *analogdb.PatchPost, id int) error { + + db.logger.Debug().Int("postID", id).Msg("Starting update post") set, args, err := patchToSet(patch) if err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to update post") return err } @@ -487,13 +541,19 @@ func updatePost(ctx context.Context, tx *sql.Tx, patch *analogdb.PatchPost, id i rows, err := tx.QueryContext(ctx, query, args...) if err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to update post") return err } defer rows.Close() + + + db.logger.Info().Int("postID", id).Msg("Finished updating post") return nil } -func insertPostUpdateTimes(ctx context.Context, tx *sql.Tx, patch *analogdb.PatchPost, id int) error { +func (db *DB) insertPostUpdateTimes(ctx context.Context, tx *sql.Tx, patch *analogdb.PatchPost, id int) error { + + db.logger.Debug().Int("postID", id).Msg("Starting post update times") query := ` @@ -505,6 +565,7 @@ func insertPostUpdateTimes(ctx context.Context, tx *sql.Tx, patch *analogdb.Patc stmt, err := tx.PrepareContext(ctx, query) if err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to post update times") return err } @@ -540,14 +601,20 @@ func insertPostUpdateTimes(ctx context.Context, tx *sql.Tx, patch *analogdb.Patc rows, err := stmt.QueryContext(ctx, values...) defer rows.Close() if err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to post update times") return err } + db.logger.Info().Int("postID", id).Msg("Finished post update times") + return nil } -func deletePost(ctx context.Context, tx *sql.Tx, id int) error { +func (db *DB) deletePost(ctx context.Context, tx *sql.Tx, id int) error { + + db.logger.Debug().Int("postID", id).Msg("Starting delete post") + query := ` DELETE FROM pictures WHERE id = $1 @@ -558,25 +625,36 @@ func deletePost(ctx context.Context, tx *sql.Tx, id int) error { var returnedID int err := row.Scan(&returnedID) if err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to delete post") return err } if id != returnedID { - return fmt.Errorf("error deleting post with id %d", id) + + err := fmt.Errorf("error deleting post with id %d", id) + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to delete post") + return err } err = tx.Commit() if err != nil { + db.logger.Error().Err(err).Int("postID", id).Msg("Failed to delete post") return err } + + db.logger.Info().Int("postID", id).Msg("Finished deleting post") return nil } -func allPostIDs(ctx context.Context, tx *sql.Tx) ([]int, error) { +func (db *DB) allPostIDs(ctx context.Context, tx *sql.Tx) ([]int, error) { + + db.logger.Debug().Msg("Starting get all post IDs") + query := ` SELECT id FROM pictures ORDER BY id ASC` rows, err := tx.QueryContext(ctx, query) if err != nil { + db.logger.Error().Err(err).Msg("Failed to get all post IDs") return nil, err } defer rows.Close() @@ -585,14 +663,18 @@ func allPostIDs(ctx context.Context, tx *sql.Tx) ([]int, error) { var id int for rows.Next() { if err := rows.Scan(&id); err != nil { + db.logger.Error().Err(err).Msg("Failed to get all post IDs") return nil, err } ids = append(ids, id) } err = tx.Commit() if err != nil { + db.logger.Error().Err(err).Msg("Failed to get all post IDs") return nil, err } + + db.logger.Info().Msg("Finished getting all post IDs") return ids, nil } diff --git a/backend/postgres/post_test.go b/backend/postgres/post_test.go index 245922b..e2ca180 100644 --- a/backend/postgres/post_test.go +++ b/backend/postgres/post_test.go @@ -31,8 +31,12 @@ var ( func TestFindPosts(t *testing.T) { t.Run("Default", func(t *testing.T) { - ctx, tx := setupTx(t) - if posts, count, err := findPosts(ctx, tx, nilFilter); err != nil { + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + + if posts, count, err := db.findPosts(ctx, tx, nilFilter); err != nil { t.Fatal(err) } else if got, want := len(posts), totalPosts; got != want { t.Fatalf("length of posts %v, want %v", got, want) @@ -42,8 +46,12 @@ func TestFindPosts(t *testing.T) { }) t.Run("Limit", func(t *testing.T) { - ctx, tx := setupTx(t) - if posts, count, err := findPosts(ctx, tx, limitFilter); err != nil { + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + + if posts, count, err := db.findPosts(ctx, tx, limitFilter); err != nil { t.Fatal(err) } else if got, want := len(posts), limit; got != want { t.Fatalf("length of posts %v, want %v", got, want) @@ -53,9 +61,13 @@ func TestFindPosts(t *testing.T) { }) t.Run("NoNSFW", func(t *testing.T) { - ctx, tx := setupTx(t) + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + nsfw := false - if posts, count, err := findPosts(ctx, tx, &analogdb.PostFilter{Nsfw: &nsfw}); err != nil { + if posts, count, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Nsfw: &nsfw}); err != nil { t.Fatal(err) } else if got, want := len(posts), totalPosts-totalNsfw; got != want { t.Fatalf("length of posts %v, want %v", got, want) @@ -65,9 +77,13 @@ func TestFindPosts(t *testing.T) { }) t.Run("OnlyNSFW", func(t *testing.T) { - ctx, tx := setupTx(t) + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + nsfw := true - if posts, count, err := findPosts(ctx, tx, &analogdb.PostFilter{Nsfw: &nsfw}); err != nil { + if posts, count, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Nsfw: &nsfw}); err != nil { t.Fatal(err) } else if got, want := len(posts), totalNsfw; got != want { t.Fatalf("length of posts %v, want %v", got, want) @@ -77,9 +93,13 @@ func TestFindPosts(t *testing.T) { }) t.Run("NoBW", func(t *testing.T) { - ctx, tx := setupTx(t) + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + grayscale := false - if posts, count, err := findPosts(ctx, tx, &analogdb.PostFilter{Grayscale: &grayscale}); err != nil { + if posts, count, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Grayscale: &grayscale}); err != nil { t.Fatal(err) } else if got, want := len(posts), totalPosts-totalGrayscale; got != want { t.Fatalf("length of posts %v, want %v", got, want) @@ -89,9 +109,13 @@ func TestFindPosts(t *testing.T) { }) t.Run("OnlyBW", func(t *testing.T) { - ctx, tx := setupTx(t) + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + grayscale := true - if posts, count, err := findPosts(ctx, tx, &analogdb.PostFilter{Grayscale: &grayscale}); err != nil { + if posts, count, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Grayscale: &grayscale}); err != nil { t.Fatal(err) } else if got, want := len(posts), totalGrayscale; got != want { t.Fatalf("length of posts %v, want %v", got, want) @@ -101,9 +125,13 @@ func TestFindPosts(t *testing.T) { }) t.Run("NoSprocket", func(t *testing.T) { - ctx, tx := setupTx(t) + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + sprocket := false - if posts, count, err := findPosts(ctx, tx, &analogdb.PostFilter{Sprocket: &sprocket}); err != nil { + if posts, count, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Sprocket: &sprocket}); err != nil { t.Fatal(err) } else if got, want := len(posts), totalPosts-totalSprocket; got != want { t.Fatalf("length of posts %v, want %v", got, want) @@ -113,9 +141,13 @@ func TestFindPosts(t *testing.T) { }) t.Run("OnlySprocket", func(t *testing.T) { - ctx, tx := setupTx(t) + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + sprocket := true - if posts, count, err := findPosts(ctx, tx, &analogdb.PostFilter{Sprocket: &sprocket}); err != nil { + if posts, count, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Sprocket: &sprocket}); err != nil { t.Fatal(err) } else if got, want := len(posts), totalSprocket; got != want { t.Fatalf("length of posts %v, want %v", got, want) @@ -125,8 +157,12 @@ func TestFindPosts(t *testing.T) { }) t.Run("ByAuthor", func(t *testing.T) { - ctx, tx := setupTx(t) - if posts, count, err := findPosts(ctx, tx, &analogdb.PostFilter{Author: &postAuthor}); err != nil { + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + + if posts, count, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Author: &postAuthor}); err != nil { t.Fatal(err) } else if len(posts) != 1 || count != 1 { t.Fatal("must be one matching post") @@ -136,9 +172,13 @@ func TestFindPosts(t *testing.T) { }) t.Run("ByAuthorAddPrefix", func(t *testing.T) { - ctx, tx := setupTx(t) + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + noPrefixAuthor := postAuthor[2:] - if posts, count, err := findPosts(ctx, tx, &analogdb.PostFilter{Author: &noPrefixAuthor}); err != nil { + if posts, count, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Author: &noPrefixAuthor}); err != nil { t.Fatal(err) } else if len(posts) != 1 || count != 1 { t.Fatal("must be one matching post") @@ -148,9 +188,13 @@ func TestFindPosts(t *testing.T) { }) t.Run("SearchTitleOne", func(t *testing.T) { - ctx, tx := setupTx(t) + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + keyword := postTitle - if posts, count, err := findPosts(ctx, tx, &analogdb.PostFilter{Title: &keyword}); err != nil { + if posts, count, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Title: &keyword}); err != nil { t.Fatal(err) } else if len(posts) != 1 || count != 1 { t.Fatal("must be one matching post") @@ -160,9 +204,13 @@ func TestFindPosts(t *testing.T) { }) t.Run("SearchTitleMultiple", func(t *testing.T) { - ctx, tx := setupTx(t) + + db := mustOpen(t) + defer mustClose(t, db) + ctx, tx := setupTx(t, db) + keyword := "Portra" - if posts, _, err := findPosts(ctx, tx, &analogdb.PostFilter{Title: &keyword}); err != nil { + if posts, _, err := db.findPosts(ctx, tx, &analogdb.PostFilter{Title: &keyword}); err != nil { t.Fatal(err) } else if got, want := len(posts), totalPortra; got != want { t.Fatalf("number of matching titles not equal, got %v, want %v", got, want) @@ -533,11 +581,9 @@ func TestPatchPost(t *testing.T) { }) } -func setupTx(t *testing.T) (context.Context, *sql.Tx) { +func setupTx(t *testing.T, db *DB) (context.Context, *sql.Tx) { t.Helper() ctx := context.Background() - db := mustOpen(t) - defer mustClose(t, db) tx, err := db.db.BeginTx(ctx, nil) if err != nil { t.Fatal(err) diff --git a/backend/postgres/postgres_test.go b/backend/postgres/postgres_test.go index f5f0806..9a44137 100644 --- a/backend/postgres/postgres_test.go +++ b/backend/postgres/postgres_test.go @@ -3,6 +3,7 @@ package postgres import ( "os" "testing" + "github.com/evanofslack/analogdb/logger" "github.com/joho/godotenv" ) @@ -19,10 +20,14 @@ func mustOpen(t *testing.T) *DB { t.Error("Error loading .env file") } + logger, err := logger.New("debug", "debug") + if err != nil { + t.Fatal(err) + } + // connect to local db for testing dsn := os.Getenv("POSTGRES_DATABASE_URL") - - db := NewDB(dsn) + db := NewDB(dsn, logger) if err := db.Open(); err != nil { t.Fatal(err) diff --git a/backend/server/authors.go b/backend/server/authors.go index 2167054..f6cf613 100644 --- a/backend/server/authors.go +++ b/backend/server/authors.go @@ -21,12 +21,12 @@ func (s *Server) mountAuthorHandlers() { func (s *Server) getAuthors(w http.ResponseWriter, r *http.Request) { authors, err := s.AuthorService.FindAuthors(r.Context()) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } authorsResponse := AuthorsResponse{ Authors: authors, } if err := encodeResponse(w, r, http.StatusOK, authorsResponse); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } diff --git a/backend/server/error.go b/backend/server/error.go index db24bf3..526041d 100644 --- a/backend/server/error.go +++ b/backend/server/error.go @@ -2,7 +2,6 @@ package server import ( "encoding/json" - "log" "net/http" "github.com/evanofslack/analogdb" @@ -23,17 +22,17 @@ func errorStatusCode(code string) int { return http.StatusInternalServerError } -func writeError(w http.ResponseWriter, r *http.Request, err error) { +func (s *Server) writeError(w http.ResponseWriter, r *http.Request, err error) { + code, message := analogdb.ErrorCode(err), analogdb.ErrorMessage(err) - if code == analogdb.ERRINTERNAL { - log.Printf("http error: %s %s: %s", r.Method, r.URL.Path, err) - } + + s.logger.Error().Err(err).Str("method", r.Method).Str("path", r.URL.Path).Str("code", code).Msg(message) w.Header().Set("Content-type", "application/json") w.WriteHeader(errorStatusCode(code)) marshallErr := json.NewEncoder(w).Encode(&ErrorResponse{Error: message}) if marshallErr != nil { - log.Fatal(marshallErr) + s.logger.Error().Err(err).Msg("Failed to marshall json") } } diff --git a/backend/server/posts.go b/backend/server/posts.go index f1ee63f..98fb893 100644 --- a/backend/server/posts.go +++ b/backend/server/posts.go @@ -83,17 +83,17 @@ func (s *Server) mountPostHandlers() { func (s *Server) getPosts(w http.ResponseWriter, r *http.Request) { filter, err := parseToFilter(r) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) return } resp, err := s.makePostResponse(r, filter) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) return } err = encodeResponse(w, r, http.StatusOK, resp) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } @@ -103,7 +103,7 @@ func (s *Server) getSimilarPosts(w http.ResponseWriter, r *http.Request) { similarityFilter, err := parseToSimilarityFilter(r) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) return } if id := chi.URLParam(r, "id"); id != "" { @@ -113,13 +113,13 @@ func (s *Server) getSimilarPosts(w http.ResponseWriter, r *http.Request) { resp.Posts = append(resp.Posts, *p) } if err := encodeResponse(w, r, http.StatusOK, resp); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } else { - writeError(w, r, err) + s.writeError(w, r, err) } } else { - writeError(w, r, err) + s.writeError(w, r, err) } } } @@ -129,31 +129,49 @@ func (s *Server) findPost(w http.ResponseWriter, r *http.Request) { if identify, err := strconv.Atoi(id); err == nil { if post, err := s.PostService.FindPostByID(r.Context(), identify); err == nil { if err := encodeResponse(w, r, http.StatusOK, post); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } else { - writeError(w, r, err) + s.writeError(w, r, err) } } else { - writeError(w, r, err) + s.writeError(w, r, err) } } } func (s *Server) deletePost(w http.ResponseWriter, r *http.Request) { - if id := chi.URLParam(r, "id"); id != "" { - if identify, err := strconv.Atoi(id); err == nil { - if err := s.PostService.DeletePost(r.Context(), identify); err == nil { - success := DeleteResponse{Message: "success, post deleted"} - if err := encodeResponse(w, r, http.StatusOK, success); err != nil { - writeError(w, r, err) - } - } else { - writeError(w, r, err) - } - } else { - writeError(w, r, err) - } + + var err error + + var id string + if id = chi.URLParam(r, "id"); id == "" { + err = &analogdb.Error{Code: analogdb.ERRUNPROCESSABLE, Message: "Must provide id as parameter"} + s.writeError(w, r, err) + return + } + + var identify int + if identify, err = strconv.Atoi(id); err != nil { + s.writeError(w, r, err) + return + } + + if err := s.PostService.DeletePost(r.Context(), identify); err != nil { + s.writeError(w, r, err) + return + } + + if err := s.SimilarityService.DeletePost(r.Context(), identify); err != nil { + s.writeError(w, r, err) + return + } + + success := DeleteResponse{Message: "success, post deleted"} + + if err := encodeResponse(w, r, http.StatusOK, success); err != nil { + s.writeError(w, r, err) + return } } @@ -161,14 +179,14 @@ func (s *Server) createPost(w http.ResponseWriter, r *http.Request) { var createPost analogdb.CreatePost if err := json.NewDecoder(r.Body).Decode(&createPost); err != nil { err = &analogdb.Error{Code: analogdb.ERRUNPROCESSABLE, Message: "error parsing post from request body"} - writeError(w, r, err) + s.writeError(w, r, err) return } // create the post in db created, err := s.PostService.CreatePost(r.Context(), &createPost) if err != nil || created == nil { - writeError(w, r, err) + s.writeError(w, r, err) return } @@ -181,7 +199,7 @@ func (s *Server) createPost(w http.ResponseWriter, r *http.Request) { toEncode := []int{created.Id} err = s.SimilarityService.BatchEncodePosts(r.Context(), toEncode, 1) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) return } } @@ -191,7 +209,7 @@ func (s *Server) createPost(w http.ResponseWriter, r *http.Request) { Post: *created, } if err := encodeResponse(w, r, http.StatusCreated, createdResponse); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } @@ -200,7 +218,7 @@ func (s *Server) patchPost(w http.ResponseWriter, r *http.Request) { var patchPost analogdb.PatchPost if err := json.NewDecoder(r.Body).Decode(&patchPost); err != nil { err = &analogdb.Error{Code: analogdb.ERRUNPROCESSABLE, Message: "error parsing patch from request body"} - writeError(w, r, err) + s.writeError(w, r, err) return } @@ -209,13 +227,13 @@ func (s *Server) patchPost(w http.ResponseWriter, r *http.Request) { if err := s.PostService.PatchPost(r.Context(), &patchPost, identify); err == nil { success := DeleteResponse{Message: "success, post patched"} if err := encodeResponse(w, r, http.StatusOK, success); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } else { - writeError(w, r, err) + s.writeError(w, r, err) } } else { - writeError(w, r, err) + s.writeError(w, r, err) } } } @@ -223,14 +241,14 @@ func (s *Server) patchPost(w http.ResponseWriter, r *http.Request) { func (s *Server) allPostIDs(w http.ResponseWriter, r *http.Request) { ids, err := s.PostService.AllPostIDs(r.Context()) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) return } idsResponse := IDsResponse{ Ids: ids, } if err := encodeResponse(w, r, http.StatusOK, idsResponse); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } diff --git a/backend/server/scrape.go b/backend/server/scrape.go index fb5b816..399e538 100644 --- a/backend/server/scrape.go +++ b/backend/server/scrape.go @@ -24,12 +24,12 @@ func (s *Server) mountScrapeHandlers() { func (s *Server) getKeywordUpdatedPosts(w http.ResponseWriter, r *http.Request) { ids, err := s.ScrapeService.KeywordUpdatedPostIDs(r.Context()) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } response := keywordsUpdatedResponse{ Ids: ids, } if err := encodeResponse(w, r, http.StatusOK, response); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } diff --git a/backend/server/server_test.go b/backend/server/server_test.go index 5bd8bb2..9ef7fe3 100644 --- a/backend/server/server_test.go +++ b/backend/server/server_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/evanofslack/analogdb/postgres" + "github.com/evanofslack/analogdb/logger" "github.com/joho/godotenv" ) @@ -15,10 +16,16 @@ func mustOpen(t *testing.T) (*Server, *postgres.DB) { t.Error("Error loading .env file") } + + logger, err := logger.New("debug", "debug") + if err != nil { + t.Fatal(err) + } + // httpserver test currently require DB, can be mocked out instead dsn := os.Getenv("POSTGRES_DATABASE_URL") - db := postgres.NewDB(dsn) + db := postgres.NewDB(dsn, logger) if err := db.Open(); err != nil { t.Fatal(err) } @@ -27,7 +34,7 @@ func mustOpen(t *testing.T) (*Server, *postgres.DB) { rs := postgres.NewReadyService(db) as := postgres.NewAuthorService(db) - s := New("8080") + s := New("8080", logger) s.PostService = ps s.ReadyService = rs s.AuthorService = as diff --git a/backend/server/similarity.go b/backend/server/similarity.go index 1985e72..5a1cbea 100644 --- a/backend/server/similarity.go +++ b/backend/server/similarity.go @@ -32,17 +32,17 @@ func (s *Server) encodePosts(w http.ResponseWriter, r *http.Request) { var request encodePostsRequest if err := json.NewDecoder(r.Body).Decode(&request); err != nil { err = &analogdb.Error{Code: analogdb.ERRUNPROCESSABLE, Message: "error parsing ids or batch_size from request body"} - writeError(w, r, err) + s.writeError(w, r, err) } err := s.SimilarityService.BatchEncodePosts(r.Context(), request.Ids, request.BatchSize) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } response := encodePostsResponse{ Message: "successfully encoded posts", } if err := encodeResponse(w, r, http.StatusOK, response); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } diff --git a/backend/server/status.go b/backend/server/status.go index e4e19be..591a6c8 100644 --- a/backend/server/status.go +++ b/backend/server/status.go @@ -16,26 +16,26 @@ func (s *Server) mountStatusHandlers() { func (s *Server) ping(w http.ResponseWriter, r *http.Request) { if err := encodeResponse(w, r, http.StatusOK, "message: pong"); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } func (s *Server) healthz(w http.ResponseWriter, r *http.Request) { if !s.healthy { err := &analogdb.Error{Code: analogdb.ERRUNAVAILABLE, Message: "Service not available"} - writeError(w, r, err) + s.writeError(w, r, err) } if err := encodeResponse(w, r, http.StatusOK, "message: healthy"); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } func (s *Server) readyz(w http.ResponseWriter, r *http.Request) { err := s.ReadyService.Readyz(r.Context()) if err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } if err := encodeResponse(w, r, http.StatusOK, "message: ready"); err != nil { - writeError(w, r, err) + s.writeError(w, r, err) } } diff --git a/backend/similarity.go b/backend/similarity.go index 38f5422..6b53627 100644 --- a/backend/similarity.go +++ b/backend/similarity.go @@ -12,6 +12,7 @@ type SimilarityService interface { EncodePost(ctx context.Context, id int) error BatchEncodePosts(ctx context.Context, ids []int, batchSize int) error FindSimilarPostsByImage(ctx context.Context, id int, filter *PostSimilarityFilter) ([]*Post, error) + DeletePost(ctx context.Context, id int) error } // used to enable encoding in http request diff --git a/backend/weaviate/batch.go b/backend/weaviate/batch.go index e913f63..0e4e218 100644 --- a/backend/weaviate/batch.go +++ b/backend/weaviate/batch.go @@ -32,12 +32,16 @@ func (ss SimilarityService) BatchEncodePosts(ctx context.Context, ids []int, bat } func (db *DB) batchUploadObjects(ctx context.Context, objects []*models.Object) error { + + db.logger.Debug().Msg("Starting batch upload to vector DB") + batcher := db.db.Batch().ObjectsBatcher() for _, obj := range objects { batcher.WithObject(obj) } _, err := batcher.Do(ctx) if err != nil { + db.logger.Error().Err(err).Msg("Failed to do batch upload to vector DB") return err } return nil diff --git a/backend/weaviate/encode.go b/backend/weaviate/encode.go index 8075387..4d9b9fd 100644 --- a/backend/weaviate/encode.go +++ b/backend/weaviate/encode.go @@ -37,12 +37,14 @@ func downloadPostImage(post *analogdb.Post) (string, error) { url := post.Images[1].Url resp, err := http.Get(url) - defer resp.Body.Close() if err != nil { + resp.Body.Close() err = fmt.Errorf("failed to request post image: %w", err) return encode, err } + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) if err != nil { err = fmt.Errorf("failed to read post image: %w", err) @@ -63,10 +65,14 @@ func postToPictureObject(post *analogdb.Post) (*models.Object, error) { } func (db *DB) uploadObject(ctx context.Context, obj *models.Object) error { + + db.logger.Debug().Msg("Starting upload object to vector DB") + batcher := db.db.Batch().ObjectsBatcher() _, err := batcher.WithObject(obj).Do(ctx) if err != nil { - err = fmt.Errorf("failed to batch to weaviate: %w", err) + err = fmt.Errorf("failed to upload to vector DB: %w", err) + db.logger.Error().Err(err).Msg("Failed upload to vector DB") return err } return nil diff --git a/backend/weaviate/schema.go b/backend/weaviate/schema.go index ba658c7..f7bff95 100644 --- a/backend/weaviate/schema.go +++ b/backend/weaviate/schema.go @@ -28,6 +28,8 @@ func (db *DB) getSchema(ctx context.Context) (*schema.Dump, error) { func (db *DB) createPictureSchema(ctx context.Context) error { + db.logger.Debug().Msg("Starting to create picture schema in vector DB") + classObj := &models.Class{ Class: "Picture", Description: "Analog photographs", @@ -75,10 +77,11 @@ func (db *DB) createPictureSchema(ctx context.Context) error { err := db.db.Schema().ClassCreator().WithClass(classObj).Do(context.Background()) if err != nil { - err = fmt.Errorf("Failed to create vector DB picture schema, %w", err) + err = fmt.Errorf("Failed to create picture schema, %w", err) + db.logger.Error().Err(err).Msg("Failed to create picture schema in vector DB") return err } - db.logger.Info().Msg("Created vector DB picture schema") + db.logger.Info().Msg("Created picture schema in vector DB") return nil } diff --git a/backend/weaviate/similarity.go b/backend/weaviate/similarity.go index 32528e3..19b2080 100644 --- a/backend/weaviate/similarity.go +++ b/backend/weaviate/similarity.go @@ -3,13 +3,17 @@ package weaviate import ( "context" "errors" + "fmt" "github.com/evanofslack/analogdb" + "github.com/weaviate/weaviate-go-client/v4/weaviate/data/replication" "github.com/weaviate/weaviate-go-client/v4/weaviate/filters" "github.com/weaviate/weaviate-go-client/v4/weaviate/graphql" "github.com/weaviate/weaviate/entities/models" ) +const PictureClass = "Picture" + var _ analogdb.SimilarityService = (*SimilarityService)(nil) type SimilarityService struct { @@ -21,6 +25,10 @@ func NewSimilarityService(db *DB, ps analogdb.PostService) *SimilarityService { return &SimilarityService{db: db, postService: ps} } +func (ss SimilarityService) DeletePost(ctx context.Context, postID int) (error) { + return ss.db.deletePost(ctx, postID) +} + func (ss SimilarityService) FindSimilarPostsByImage(ctx context.Context, postID int, similarityFilter *analogdb.PostSimilarityFilter) ([]*analogdb.Post, error) { var posts []*analogdb.Post @@ -41,6 +49,50 @@ func (ss SimilarityService) FindSimilarPostsByImage(ctx context.Context, postID return posts, err } + +func (db *DB) deletePost(ctx context.Context, postID int) (error) { + + db.logger.Debug().Int("postID", postID).Msg("Starting delete post from vector DB") + + where := filters.Where(). + WithPath([]string{"post_id"}). + WithOperator(filters.Equal). + WithValueInt(int64(postID)) + + result, err := db.db.GraphQL().Get(). + WithClassName(PictureClass). + WithLimit(1). + WithWhere(where). + Do(ctx) + + if err != nil { + err = fmt.Errorf("Failed to find postID in vector DB, err=%w", err) + db.logger.Error().Err(err).Int("postID", postID).Msg("Failed to delete post from vectorDB") + return &analogdb.Error{Code: analogdb.ERRNOTFOUND, Message: fmt.Sprintf("Post %d not found", postID)} + } + + pics, err := unmarshallPicturesResp(result) + if err != nil { + db.logger.Error().Err(err).Int("postID", postID).Msg("Failed to delete post from vector DB") + return &analogdb.Error{Code: analogdb.ERRNOTFOUND, Message: fmt.Sprintf("Post %d not found", postID)} + } + + err = db.db.Data().Deleter(). + WithClassName(PictureClass). + WithID(pics[0].uuid). + WithConsistencyLevel(replication.ConsistencyLevel.ALL). // default QUORUM + Do(ctx) + + if err != nil { + db.logger.Error().Err(err).Int("postID", postID).Msg("Failed to delete post from vector DB") + return &analogdb.Error{Code: analogdb.ERRINTERNAL, Message: fmt.Sprintf("Post %d could not be deleted from vector DB", postID)} + } + + db.logger.Info().Int("postID", postID).Msg("Deleted post from vector DB") + + return err +} + type pictureResponse struct { postID int distance float64 @@ -49,6 +101,8 @@ type pictureResponse struct { func (db *DB) getSimilarPostIDs(ctx context.Context, postID int, filter *analogdb.PostSimilarityFilter) ([]int, error) { + db.logger.Debug().Int("postID", postID).Msg("Starting get similar posts from vector DB") + var ids []int // first make the query to lookup UUID associated with post's embedding @@ -74,12 +128,14 @@ func (db *DB) getSimilarPostIDs(ctx context.Context, postID int, filter *analogd Do(ctx) if err != nil { + db.logger.Error().Err(err).Int("postID", postID).Msg("Failed to find post in vector DB") return ids, err } pics, err := unmarshallPicturesResp(result) - if len(pics) == 0 { - return ids, &analogdb.Error{Code: analogdb.ERRNOTFOUND, Message: "Post not found"} + if err != nil { + db.logger.Error().Err(err).Int("postID", postID).Msg("Failed to unmarshall post from vector DB") + return ids, &analogdb.Error{Code: analogdb.ERRNOTFOUND, Message: fmt.Sprintf("Post %d not found", postID)} } // then make query to find nearest neighbors @@ -87,6 +143,7 @@ func (db *DB) getSimilarPostIDs(ctx context.Context, postID int, filter *analogd // this is where we narrow down the results where, err = filterToWhere(filter) if err != nil { + db.logger.Error().Err(err).Int("postID", postID).Msg("Failed to convert similarity filter to where clause") return ids, err } @@ -106,11 +163,13 @@ func (db *DB) getSimilarPostIDs(ctx context.Context, postID int, filter *analogd Do(ctx) if err != nil { + db.logger.Error().Err(err).Int("postID", postID).Msg("Failed to find near posts in vector DB") return ids, err } pics, err = unmarshallPicturesResp(result) if err != nil { + db.logger.Error().Err(err).Int("postID", postID).Msg("Failed to unmarshall post from vector DB") return ids, err } @@ -119,6 +178,7 @@ func (db *DB) getSimilarPostIDs(ctx context.Context, postID int, filter *analogd } if len(ids) == 0 { + db.logger.Error().Err(err).Int("postID", postID).Msg("Found zero similar posts") return ids, &analogdb.Error{Code: analogdb.ERRNOTFOUND, Message: "No similar posts found"} } @@ -202,5 +262,7 @@ func unmarshallPicturesResp(result *models.GraphQLResponse) ([]pictureResponse, if len(picturesResponse) > 0 { return picturesResponse, nil } - return picturesResponse, errors.New("Failed to unmarshall pictures from vector DB") + + err := errors.New("Failed to unmarshall pictures from vector DB") + return picturesResponse, err } diff --git a/backend/weaviate/weaviate.go b/backend/weaviate/weaviate.go index c275d31..40005b3 100644 --- a/backend/weaviate/weaviate.go +++ b/backend/weaviate/weaviate.go @@ -24,12 +24,14 @@ type DB struct { func NewDB(host string, scheme string, logger *logger.Logger) *DB { db := &DB{host: host, scheme: scheme, timeout: weaviateClientTimeout, logger: logger} db.ctx, db.cancel = context.WithCancel(context.Background()) - db.logger.Logger.Info().Msg("Initialized vector DB instance") + db.logger.Info().Msg("Initialized vector DB instance") return db } func (db *DB) Open() error { + db.logger.Debug().Msg("Starting vector DB open") + // validate host and scheme are set if db.host == "" { return fmt.Errorf("Vector DB host must be set") @@ -48,14 +50,18 @@ func (db *DB) Open() error { db.db, err = weaviate.NewClient(cfg) if err != nil { err = fmt.Errorf("Failed to create new vector DB client: %w", err) + db.logger.Error().Err(err).Msg("Failed to open vector DB") return err } - db.logger.Logger.Info().Msg("Opened new vector DB connection") + db.logger.Info().Msg("Opened new vector DB connection") return err } func (db *DB) Migrate(ctx context.Context) error { + + db.logger.Debug().Msg("Starting vector DB migration") + schema, err := db.getSchema(ctx) if err != nil { err = fmt.Errorf("Failed to get weaviate schema: %w", err) @@ -68,12 +74,13 @@ func (db *DB) Migrate(ctx context.Context) error { return err } } - db.logger.Logger.Info().Msg("Completed vector DB migration") + db.logger.Info().Msg("Completed vector DB migration") return nil } func (db *DB) Close() error { + db.logger.Debug().Msg("Starting vector DB close") db.cancel() - db.logger.Logger.Info().Msg("Closed vector DB connection") + db.logger.Info().Msg("Closed vector DB connection") return nil } diff --git a/web/package.json b/web/package.json index 5185f82..576284c 100644 --- a/web/package.json +++ b/web/package.json @@ -1,5 +1,5 @@ { - "name": "my-app", + "name": "analogdb-web", "private": true, "scripts": { "dev": "next dev",