diff --git a/src/app/views/albums.zig b/src/app/views/albums.zig index af72456..9c6063e 100644 --- a/src/app/views/albums.zig +++ b/src/app/views/albums.zig @@ -3,31 +3,81 @@ const jetzig = @import("jetzig"); const jetquery = @import("jetzig").jetquery; const TableRow = @import("../../types.zig").TableRow; const HyperlinkData = @import("../../types.zig").HyperlinkData; -const queries = @import("../../queries.zig"); pub fn index(request: *jetzig.Request) !jetzig.View { var root = try request.data(.object); + var albums_view = try root.put("albums", .array); + const query = + \\SELECT albums.name, albums.id, artists.name, artists.id, COUNT(scrobbles) AS scrobbles + \\FROM albumsongs + \\INNER JOIN albums ON albumsongs.album_id = albums.id + \\INNER JOIN scrobbles ON albumsongs.id = scrobbles.albumsong + \\INNER JOIN artistalbums ON artistalbums.album_id = albums.id + \\INNER JOIN artists ON artists.id = artistalbums.artist_id + \\GROUP BY albums.id, artists.id + \\ORDER BY scrobbles DESC + ; - const albums = try queries.entityQueryResult(request, queries.generateQuery(.album, .entities), .{}, .array); - try root.put("albums", albums); + var albums_jq_result = try request.repo.executeSql(query, .{}); + defer albums_jq_result.deinit(); + const Album = struct { name: []const u8, id: i32, artist_name: []const u8, artist_id: i32, scrobbles: i64 }; + + var prev_album_id: ?i32 = null; + + var row: ?TableRow = null; + var artistlist = std.ArrayList(HyperlinkData).init(request.allocator); + + blk: while (try albums_jq_result.postgresql.result.next()) |album_row| { + const album = try album_row.to(Album, .{ .dupe = true, .allocator = request.allocator }); + if (album.id == prev_album_id) { + try artistlist.append(.{ .name = album.artist_name, .id = album.artist_id }); + continue :blk; + } else { + try artistlist.append(.{ .name = album.artist_name, .id = album.artist_id }); + + row = TableRow{ + .album = .{ .name = album.name, .id = album.id }, + .artistlist = try artistlist.toOwnedSlice(), + .scrobbles = album.scrobbles, + }; + + try albums_view.append(row); + } + prev_album_id = album.id; + } return request.render(.ok); } pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View { var root = try request.data(.object); + var songs_view = try root.put("songs", .array); + const album_name = try jetzig.database.Query(.Album).find(id).select(.{ .id, .name }).execute(request.repo); + _ = try root.put("album", album_name.?.name); - const album = try queries.entityQueryResult(request, queries.generateQuery(.album, .entity_info), .{id}, .object); - try root.put("album", album.get("entity_info")); + const query = + \\SELECT songs.name, songs.id, COUNT(scrobbles) AS scrobbles + \\FROM albumsongs + \\INNER JOIN songs ON albumsongs.song_id = songs.id + \\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id + \\WHERE albumsongs.album_id = $1 + \\GROUP BY songs.id + \\ORDER BY scrobbles DESC + ; - const songs = try queries.entityQueryResult(request, queries.generateQuery(.album, .entity_items), .{id}, .array); - try root.put("songs", songs); + var songs_js_result = try request.repo.executeSql(query, .{id}); + defer songs_js_result.deinit(); - const firstlast = try queries.entityQueryResult(request, queries.generateQuery(.album, .firstlast), .{id}, .array); - try root.put("firstlast", firstlast); + const Song = struct { name: []const u8, id: i32, scrobbles: i64 }; - const timescale = try queries.entityQueryResult(request, queries.generateQuery(.album, .timescale), .{id}, .array); - try root.put("yearly", timescale); + while (try songs_js_result.postgresql.result.next()) |song_row| { + const song = try song_row.to(Song, .{ .dupe = true, .allocator = request.allocator }); + const row = TableRow{ + .song = .{ .name = song.name, .id = song.id }, + .scrobbles = song.scrobbles, + }; + try songs_view.append(row); + } return request.render(.ok); } diff --git a/src/app/views/albums/get.zmpl b/src/app/views/albums/get.zmpl index 1024ec5..3a1641b 100644 --- a/src/app/views/albums/get.zmpl +++ b/src/app/views/albums/get.zmpl @@ -10,10 +10,6 @@
@partial partials/header