diff --git a/cmd/api/movies.go b/cmd/api/movies.go index c8bc40c..dacd6fc 100644 --- a/cmd/api/movies.go +++ b/cmd/api/movies.go @@ -236,12 +236,16 @@ func (app *application) listMoviesHandler(w http.ResponseWriter, r *http.Request return } - // Check the Validator instance for any errors and use the failedValidationResponse() helper to send the client a response if necessary - if !v.Valid() { - app.failedValidationResponse(w, r, v.Errors) + // Call the GetAll() method to retrieve the movies, passing in the various filter parameters. + movies, err := app.models.Movies.GetAll(input.Title, input.Genres, input.Filters) + if err != nil { + app.serverErrorResponse(w, r, err) return } - // Dump the contents of the input struct in a HTTP response - fmt.Fprintf(w, "%+v\n", input) + // Send a JSON response containing the movie data + err = app.writeJSON(w, http.StatusOK, envelope{"movies": movies}, nil) + if err != nil { + app.serverErrorResponse(w, r, err) + } } diff --git a/internal/data/movies.go b/internal/data/movies.go index c8277bc..79011e0 100644 --- a/internal/data/movies.go +++ b/internal/data/movies.go @@ -191,3 +191,60 @@ func (m MovieModel) Delete(id int64) error { return nil } + +// GetAll : Returns a slice of movies. Although we're not using them right now, we've set this up to accept the various filter parameters as arguments +func (m MovieModel) GetAll(title string, genres []string, filters Filters) ([]*Movie, error) { + // Construct the SQL query to retrieve all movie records. + query := ` + SELECT id, created_at, title, year, runtime, genres, version + FROM movies + ORDER BY id` + + // Create a context with a 3-second timeout + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + // Use QueryContext() to execute the query. This returns a sql.Rows resultset containing the result + rows, err := m.DB.QueryContext(ctx, query) + if err != nil { + return nil, err + } + + // Importantly, defer a call to rows.Close() to ensure the resultset is closed before GetAll() returns + defer rows.Close() + + // Initialize an empty slice to hold the movie data. + movies := []*Movie{} + + // Use rows.Next to iterate through the rows in the resultset. + for rows.Next() { + // Initialize an empty Movie struct to hold the data for an individual movie. + var movie Movie + + // Scan the values from the row into the Movie struct. Again, note that we're using the pq.Array() adapter on the genres field here. + err := rows.Scan( + &movie.ID, + &movie.CreatedAt, + &movie.Title, + &movie.Year, + &movie.Runtime, + pq.Array(&movie.Genres), + &movie.Version, + ) + if err != nil { + return nil, err + } + + // Add the Movie struct to the slice. + movies = append(movies, &movie) + } + + // When the rows.Next() loop has finished, call rows.Err() to retrieve any error that was encountered during the iteration. + if err = rows.Err(); err != nil { + return nil, err + } + + // If everything went OK, then return the slice of movies + return movies, nil + +}