Merge remote-tracking branch 'refs/remotes/origin/rawsql' into rawsql
This commit is contained in:
commit
df8f01525e
18 changed files with 253 additions and 138 deletions
|
|
@ -4,7 +4,7 @@ pub const Album = jetquery.Model(
|
|||
@This(),
|
||||
"albums",
|
||||
struct {
|
||||
id: i32,
|
||||
id: i64,
|
||||
name: []const u8,
|
||||
length: ?f32,
|
||||
created_at: jetquery.DateTime,
|
||||
|
|
@ -22,9 +22,9 @@ pub const Albumsong = jetquery.Model(
|
|||
@This(),
|
||||
"albumsongs",
|
||||
struct {
|
||||
id: i32,
|
||||
song_id: i32,
|
||||
album_id: i32,
|
||||
id: i64,
|
||||
song_id: i64,
|
||||
album_id: i64,
|
||||
created_at: jetquery.DateTime,
|
||||
updated_at: jetquery.DateTime,
|
||||
},
|
||||
|
|
@ -32,9 +32,7 @@ pub const Albumsong = jetquery.Model(
|
|||
.relations = .{
|
||||
.song = jetquery.belongsTo(.Song, .{}),
|
||||
.album = jetquery.belongsTo(.Album, .{}),
|
||||
.scrobbles = jetquery.hasMany(.Scrobble, .{
|
||||
.foreign_key = "albumsong",
|
||||
}),
|
||||
.scrobbles = jetquery.hasMany(.Scrobble, .{ .foreign_key = "albumsong" }),
|
||||
.albumsongsartists = jetquery.hasMany(.Albumsongsartist, .{}),
|
||||
},
|
||||
},
|
||||
|
|
@ -44,9 +42,9 @@ pub const Albumsongsartist = jetquery.Model(
|
|||
@This(),
|
||||
"albumsongsartists",
|
||||
struct {
|
||||
id: i32,
|
||||
albumsong_id: i32,
|
||||
artist_id: i32,
|
||||
id: i64,
|
||||
albumsong_id: i64,
|
||||
artist_id: i64,
|
||||
created_at: jetquery.DateTime,
|
||||
updated_at: jetquery.DateTime,
|
||||
},
|
||||
|
|
@ -62,9 +60,9 @@ pub const Artistalbum = jetquery.Model(
|
|||
@This(),
|
||||
"artistalbums",
|
||||
struct {
|
||||
id: i32,
|
||||
album_id: i32,
|
||||
artist_id: i32,
|
||||
id: i64,
|
||||
album_id: i64,
|
||||
artist_id: i64,
|
||||
created_at: jetquery.DateTime,
|
||||
updated_at: jetquery.DateTime,
|
||||
},
|
||||
|
|
@ -80,7 +78,7 @@ pub const Artist = jetquery.Model(
|
|||
@This(),
|
||||
"artists",
|
||||
struct {
|
||||
id: i32,
|
||||
id: i64,
|
||||
name: []const u8,
|
||||
disambiguation: ?[]const u8,
|
||||
created_at: jetquery.DateTime,
|
||||
|
|
@ -90,6 +88,7 @@ pub const Artist = jetquery.Model(
|
|||
.relations = .{
|
||||
.albumsongsartists = jetquery.hasMany(.Albumsongsartist, .{}),
|
||||
.artistalbums = jetquery.hasMany(.Artistalbum, .{}),
|
||||
.artistsongs = jetquery.hasMany(.Artistsong, .{}),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -98,17 +97,15 @@ pub const Scrobble = jetquery.Model(
|
|||
@This(),
|
||||
"scrobbles",
|
||||
struct {
|
||||
id: i32,
|
||||
albumsong: i32,
|
||||
id: i64,
|
||||
albumsong: i64,
|
||||
datetime: jetquery.DateTime,
|
||||
created_at: jetquery.DateTime,
|
||||
updated_at: jetquery.DateTime,
|
||||
},
|
||||
.{
|
||||
.relations = .{
|
||||
.albumsong = jetquery.belongsTo(.Albumsong, .{
|
||||
.foreign_key = "albumsong",
|
||||
}),
|
||||
.albumsong = jetquery.belongsTo(.Albumsong, .{ .foreign_key = "albumsong" }),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
@ -117,7 +114,7 @@ pub const Song = jetquery.Model(
|
|||
@This(),
|
||||
"songs",
|
||||
struct {
|
||||
id: i32,
|
||||
id: i64,
|
||||
name: []const u8,
|
||||
length: ?f32,
|
||||
hidden: bool,
|
||||
|
|
@ -127,6 +124,25 @@ pub const Song = jetquery.Model(
|
|||
.{
|
||||
.relations = .{
|
||||
.albumsongs = jetquery.hasMany(.Albumsong, .{}),
|
||||
.artistsongs = jetquery.hasMany(.Artistsong, .{}),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
pub const Artistsong = jetquery.Model(
|
||||
@This(),
|
||||
"artistsongs",
|
||||
struct {
|
||||
id: i64,
|
||||
artist_id: i64,
|
||||
song_id: i64,
|
||||
created_at: jetquery.DateTime,
|
||||
updated_at: jetquery.DateTime,
|
||||
},
|
||||
.{
|
||||
.relations = .{
|
||||
.artist = jetquery.belongsTo(.Artist, .{}),
|
||||
.song = jetquery.belongsTo(.Song, .{}),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ pub fn up(repo: anytype) !void {
|
|||
try repo.createTable(
|
||||
"songs",
|
||||
&.{
|
||||
t.primaryKey("id", .{}),
|
||||
t.primaryKey("id", .{ .type = .bigint }),
|
||||
t.column("name", .string, .{}),
|
||||
t.column("length", .float, .{ .optional = true }),
|
||||
t.column("hidden", .boolean, .{}),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ pub fn up(repo: anytype) !void {
|
|||
try repo.createTable(
|
||||
"albums",
|
||||
&.{
|
||||
t.primaryKey("id", .{}),
|
||||
t.primaryKey("id", .{ .type = .bigint }),
|
||||
t.column("name", .string, .{}),
|
||||
t.column("length", .float, .{ .optional = true }),
|
||||
t.timestamps(.{}),
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ pub fn up(repo: anytype) !void {
|
|||
try repo.createTable(
|
||||
"albumsongs",
|
||||
&.{
|
||||
t.primaryKey("id", .{}),
|
||||
t.column("song_id", .integer, .{ .reference = .{ "songs", "id" } }),
|
||||
t.column("album_id", .integer, .{ .reference = .{ "albums", "id" } }),
|
||||
t.primaryKey("id", .{ .type = .bigint }),
|
||||
t.column("song_id", .bigint, .{ .reference = .{ "songs", "id" } }),
|
||||
t.column("album_id", .bigint, .{ .reference = .{ "albums", "id" } }),
|
||||
t.timestamps(.{}),
|
||||
},
|
||||
.{},
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ pub fn up(repo: anytype) !void {
|
|||
try repo.createTable(
|
||||
"scrobbles",
|
||||
&.{
|
||||
t.primaryKey("id", .{}),
|
||||
t.column("albumsong", .integer, .{ .reference = .{ "albumsongs", "id" } }),
|
||||
t.primaryKey("id", .{ .type = .bigint }),
|
||||
t.column("albumsong", .bigint, .{ .reference = .{ "albumsongs", "id" } }),
|
||||
t.column("datetime", .datetime, .{}),
|
||||
t.timestamps(.{}),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ pub fn up(repo: anytype) !void {
|
|||
try repo.createTable(
|
||||
"artists",
|
||||
&.{
|
||||
t.primaryKey("id", .{}),
|
||||
t.primaryKey("id", .{ .type = .bigint }),
|
||||
t.column("name", .string, .{}),
|
||||
t.column("disambiguation", .string, .{ .optional = true }),
|
||||
t.timestamps(.{}),
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ pub fn up(repo: anytype) !void {
|
|||
try repo.createTable(
|
||||
"albumsongsartists",
|
||||
&.{
|
||||
t.primaryKey("id", .{}),
|
||||
t.column("albumsong_id", .integer, .{ .reference = .{ "albumsongs", "id" } }),
|
||||
t.column("artist_id", .integer, .{ .reference = .{ "artists", "id" } }),
|
||||
t.primaryKey("id", .{ .type = .bigint }),
|
||||
t.column("albumsong_id", .bigint, .{ .reference = .{ "albumsongs", "id" } }),
|
||||
t.column("artist_id", .bigint, .{ .reference = .{ "artists", "id" } }),
|
||||
t.timestamps(.{}),
|
||||
},
|
||||
.{},
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ pub fn up(repo: anytype) !void {
|
|||
try repo.createTable(
|
||||
"artistalbums",
|
||||
&.{
|
||||
t.primaryKey("id", .{}),
|
||||
t.column("album_id", .integer, .{ .reference = .{ "albums", "id" } }),
|
||||
t.column("artist_id", .integer, .{ .reference = .{ "artists", "id" } }),
|
||||
t.primaryKey("id", .{ .type = .bigint }),
|
||||
t.column("album_id", .bigint, .{ .reference = .{ "albums", "id" } }),
|
||||
t.column("artist_id", .bigint, .{ .reference = .{ "artists", "id" } }),
|
||||
t.timestamps(.{}),
|
||||
},
|
||||
.{},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
const std = @import("std");
|
||||
const jetquery = @import("jetquery");
|
||||
const t = jetquery.schema.table;
|
||||
|
||||
pub fn up(repo: anytype) !void {
|
||||
try repo.createTable(
|
||||
"artistsongs",
|
||||
&.{
|
||||
t.primaryKey("id", .{ .type = .bigint }),
|
||||
t.column("artist_id", .bigint, .{ .reference = .{ "artists", "id" } }),
|
||||
t.column("song_id", .bigint, .{ .reference = .{ "songs", "id" } }),
|
||||
t.timestamps(.{}),
|
||||
},
|
||||
.{},
|
||||
);
|
||||
}
|
||||
|
||||
pub fn down(repo: anytype) !void {
|
||||
try repo.dropTable("artistsongs", .{});
|
||||
}
|
||||
|
|
@ -20,12 +20,13 @@ pub fn run(allocator: std.mem.Allocator, params: *jetzig.data.Value, env: jetzig
|
|||
|
||||
// Probably want to include artist name here, but not sure how to yet
|
||||
|
||||
const track_artist_count = item.getT(.array, "artists_track").?.count();
|
||||
const album_artist_count = item.getT(.array, "artists_album").?.count();
|
||||
var track_artist_name_buffer = try allocator.alloc([]const u8, track_artist_count);
|
||||
var album_artist_name_buffer = try allocator.alloc([]const u8, album_artist_count);
|
||||
var track_artist_id_buffer = try allocator.alloc(i32, track_artist_count);
|
||||
var album_artist_id_buffer = try allocator.alloc(i32, album_artist_count);
|
||||
const track_artists = item.getT(.array, "artists_track").?.items();
|
||||
const album_artists = item.getT(.array, "artists_album").?.items();
|
||||
|
||||
var track_artist_name_buffer = try allocator.alloc([]const u8, track_artists.len);
|
||||
var album_artist_name_buffer = try allocator.alloc([]const u8, album_artists.len);
|
||||
var track_artist_id_buffer = try allocator.alloc(i64, track_artists.len);
|
||||
var album_artist_id_buffer = try allocator.alloc(i64, album_artists.len);
|
||||
|
||||
const scrobble: Data.Scrobble = .{
|
||||
.track = item.getT(.string, "track").?,
|
||||
|
|
@ -35,95 +36,99 @@ pub fn run(allocator: std.mem.Allocator, params: *jetzig.data.Value, env: jetzig
|
|||
.date = @as(i64, @truncate(item.getT(.integer, "date").?)),
|
||||
};
|
||||
|
||||
var id_prehash = std.ArrayList(u8).init(allocator);
|
||||
var album_hash_string = std.ArrayList(u8).init(allocator);
|
||||
var track_hash_string = std.ArrayList(u8).init(allocator);
|
||||
|
||||
for (item.getT(.array, "artists_track").?.items(), 0..track_artist_count) |artist, i| {
|
||||
// I theoretically don't need this for loop
|
||||
for (track_artists, 0..track_artists.len) |artist, i| {
|
||||
const artist_name = try artist.coerce([]const u8);
|
||||
track_artist_name_buffer[i] = artist_name;
|
||||
track_artist_id_buffer[i] = @as(i32, @bitCast(std.hash.Fnv1a_32.hash(artist_name)));
|
||||
track_artist_id_buffer[i] = @as(i64, @bitCast(std.hash.Fnv1a_64.hash(artist_name)));
|
||||
}
|
||||
|
||||
for (item.getT(.array, "artists_album").?.items(), 0..album_artist_count) |artist, i| {
|
||||
for (album_artists, 0..album_artists.len) |artist, i| {
|
||||
const artist_name = try artist.coerce([]const u8);
|
||||
album_artist_name_buffer[i] = artist_name;
|
||||
album_artist_id_buffer[i] = @as(i32, @bitCast(std.hash.Fnv1a_32.hash(artist_name)));
|
||||
try id_prehash.appendSlice(artist_name);
|
||||
album_artist_id_buffer[i] = @as(i64, @bitCast(std.hash.Fnv1a_32.hash(artist_name)));
|
||||
try album_hash_string.appendSlice(artist_name);
|
||||
}
|
||||
|
||||
try id_prehash.appendSlice(scrobble.album);
|
||||
const album_id = @as(i32, @bitCast(std.hash.Fnv1a_32.hash(id_prehash.items)));
|
||||
try id_prehash.appendSlice(scrobble.track);
|
||||
const song_id = @as(i32, @bitCast(std.hash.Fnv1a_32.hash(id_prehash.items)));
|
||||
try album_hash_string.appendSlice(scrobble.album);
|
||||
try track_hash_string.appendSlice(scrobble.album);
|
||||
const album_hash = @as(i64, @bitCast(std.hash.Fnv1a_32.hash(album_hash_string.items)));
|
||||
try track_hash_string.appendSlice(scrobble.track);
|
||||
const track_hash = @as(i64, @bitCast(std.hash.Fnv1a_32.hash(track_hash_string.items)));
|
||||
|
||||
var albumsong = try jetzig.database.Query(.Albumsong)
|
||||
.findBy(.{ .album_id = album_id, .song_id = song_id })
|
||||
var albumsong_id = try jetzig.database.Query(.Albumsong)
|
||||
.find(album_hash ^ track_hash)
|
||||
.select(.{.id}).execute(env.repo);
|
||||
|
||||
var ins_album = try jetzig.database.Query(.Album)
|
||||
.find(album_id)
|
||||
var album_id = try jetzig.database.Query(.Album)
|
||||
.find(album_hash)
|
||||
.select(.{.id}).execute(env.repo);
|
||||
|
||||
for (track_artist_name_buffer, track_artist_id_buffer) |artist_name, artist_id| {
|
||||
var ins_artist = try jetzig.database.Query(.Artist)
|
||||
.find(artist_id)
|
||||
for (track_artist_name_buffer, track_artist_id_buffer) |scrobble_track_artist, track_artist_hash| {
|
||||
var artist_id = try jetzig.database.Query(.Artist)
|
||||
.find(track_artist_hash)
|
||||
.select(.{.id}).execute(env.repo);
|
||||
|
||||
if (ins_artist == null)
|
||||
ins_artist = try jetzig.database.Query(.Artist)
|
||||
.insert(.{ .id = artist_id, .name = artist_name, .disambiguation = null })
|
||||
if (artist_id == null)
|
||||
artist_id = try jetzig.database.Query(.Artist)
|
||||
.insert(.{ .id = track_artist_hash, .name = scrobble_track_artist, .disambiguation = null })
|
||||
.returning(.{.id}).execute(env.repo);
|
||||
|
||||
if (albumsong == null) {
|
||||
var ins_song = try jetzig.database.Query(.Song)
|
||||
.find(song_id)
|
||||
if (albumsong_id == null) {
|
||||
var track_id = try jetzig.database.Query(.Song)
|
||||
.find(track_hash)
|
||||
.select(.{.id}).execute(env.repo);
|
||||
|
||||
if (ins_song == null)
|
||||
ins_song = try jetzig.database.Query(.Song)
|
||||
.insert(.{ .id = song_id, .name = scrobble.track, .length = null, .hidden = false })
|
||||
if (track_id == null)
|
||||
track_id = try jetzig.database.Query(.Song)
|
||||
.insert(.{ .id = track_hash, .name = scrobble.track, .length = null, .hidden = false })
|
||||
.returning(.{.id}).execute(env.repo);
|
||||
|
||||
if (ins_album == null)
|
||||
ins_album = try jetzig.database.Query(.Album)
|
||||
.insert(.{ .id = album_id, .name = scrobble.album, .length = null })
|
||||
if (album_id == null)
|
||||
album_id = try jetzig.database.Query(.Album)
|
||||
.insert(.{ .id = album_hash, .name = scrobble.album, .length = null })
|
||||
.returning(.{.id}).execute(env.repo);
|
||||
|
||||
albumsong = try jetzig.database.Query(.Albumsong)
|
||||
.insert(.{ .song_id = ins_song.?.id, .album_id = ins_album.?.id })
|
||||
albumsong_id = try jetzig.database.Query(.Albumsong)
|
||||
.insert(.{ .song_id = track_id.?.id, .album_id = album_id.?.id })
|
||||
.returning(.{.id}).execute(env.repo);
|
||||
|
||||
try jetzig.database.Query(.Albumsongsartist)
|
||||
.insert(.{ .albumsong_id = albumsong.?.id, .artist_id = ins_artist.?.id }).execute(env.repo);
|
||||
.insert(.{ .albumsong_id = albumsong_id.?.id, .artist_id = artist_id.?.id }).execute(env.repo);
|
||||
} else {
|
||||
const ins_albumsongartist = try jetzig.database.Query(.Albumsongsartist)
|
||||
.findBy(.{ .albumsong_id = albumsong.?.id, .artist_id = ins_artist.?.id })
|
||||
.findBy(.{ .albumsong_id = albumsong_id.?.id, .artist_id = artist_id.?.id })
|
||||
.select(.{.id}).execute(env.repo);
|
||||
|
||||
if (ins_albumsongartist == null)
|
||||
try jetzig.database.Query(.Albumsongsartist)
|
||||
.insert(.{ .albumsong_id = albumsong.?.id, .artist_id = ins_artist.?.id }).execute(env.repo);
|
||||
.insert(.{ .albumsong_id = albumsong_id.?.id, .artist_id = artist_id.?.id }).execute(env.repo);
|
||||
}
|
||||
}
|
||||
for (album_artist_name_buffer, album_artist_id_buffer) |artist_name, artist_id| {
|
||||
const ins_artistalbum = try jetzig.database.Query(.Artistalbum)
|
||||
.findBy(.{ .album_id = ins_album.?.id, .artist_id = artist_id })
|
||||
|
||||
for (album_artist_name_buffer, album_artist_id_buffer) |scrobble_album_artist, album_artist_hash| {
|
||||
const artistalbum_id = try jetzig.database.Query(.Artistalbum)
|
||||
.findBy(.{ .album_id = album_id.?.id, .artist_id = album_artist_hash })
|
||||
.select(.{.id}).execute(env.repo);
|
||||
|
||||
if (ins_artistalbum == null) {
|
||||
var ins_artist = try jetzig.database.Query(.Artist)
|
||||
.find(artist_id)
|
||||
if (artistalbum_id == null) {
|
||||
var artist_id = try jetzig.database.Query(.Artist)
|
||||
.find(album_artist_hash)
|
||||
.select(.{.id}).execute(env.repo);
|
||||
if (ins_artist == null)
|
||||
ins_artist = try jetzig.database.Query(.Artist)
|
||||
.insert(.{ .id = artist_id, .name = artist_name, .disambiguation = null })
|
||||
if (artist_id == null)
|
||||
artist_id = try jetzig.database.Query(.Artist)
|
||||
.insert(.{ .id = artist_id, .name = scrobble_album_artist, .disambiguation = null })
|
||||
.returning(.{.id}).execute(env.repo);
|
||||
try jetzig.database.Query(.Artistalbum)
|
||||
.insert(.{ .album_id = ins_album.?.id, .artist_id = ins_artist.?.id }).execute(env.repo);
|
||||
.insert(.{ .album_id = album_id.?.id, .artist_id = artist_id.?.id }).execute(env.repo);
|
||||
}
|
||||
}
|
||||
|
||||
try jetzig.database.Query(.Scrobble)
|
||||
.insert(.{ .albumsong = albumsong.?.id, .datetime = scrobble.date }).execute(env.repo);
|
||||
.insert(.{ .albumsong = albumsong_id.?.id, .datetime = scrobble.date }).execute(env.repo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
|
|||
const album = try queries.entityQueryResult(request, queries.loadQuery(.album, .entity_info), .{id});
|
||||
try root.put("album", album);
|
||||
|
||||
const songs = try queries.entityQueryResult(request, queries.loadQuery(.album, .entity_items), .{id});
|
||||
const songs = try queries.entityQueryResult(request, queries.loadQuery(.album, .get_songs), .{id});
|
||||
try root.put("songs", songs);
|
||||
|
||||
const firstlast = try queries.entityQueryResult(request, queries.loadQuery(.album, .firstlast), .{id});
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
|
|||
const artist = try queries.entityQueryResult(request, queries.loadQuery(.artist, .entity_info), .{id});
|
||||
try root.put("artist", artist);
|
||||
|
||||
const albums = try queries.entityQueryResult(request, queries.loadQuery(.artist, .entity_items), .{id});
|
||||
const albums = try queries.entityQueryResult(request, queries.loadQuery(.artist, .get_albums), .{id});
|
||||
try root.put("albums", albums);
|
||||
|
||||
const appears = try queries.entityQueryResult(request, queries.loadQuery(.artist, .appears), .{id});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
@args T: type, table_data: *ZmplValue, columns: T
|
||||
|
||||
<div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
@ -70,4 +71,5 @@
|
|||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
|
|
@ -25,11 +25,11 @@ pub fn get(id: []const u8, request: *jetzig.Request) !jetzig.View {
|
|||
const song = try queries.entityQueryResult(request, queries.loadQuery(.song, .entity_info), .{id});
|
||||
try root.put("song", song);
|
||||
|
||||
const scrobbles = try queries.entityQueryResult(request, queries.loadQuery(.song, .entity_items), .{id});
|
||||
const scrobbles = try queries.entityQueryResult(request, queries.loadQuery(.song, .get_scrobbles), .{id});
|
||||
try root.put("scrobbles", scrobbles);
|
||||
|
||||
const appears = try queries.entityQueryResult(request, queries.loadQuery(.song, .appears), .{id});
|
||||
try root.put("appears", appears);
|
||||
const albums = try queries.entityQueryResult(request, queries.loadQuery(.song, .get_albums), .{id});
|
||||
try root.put("albums", albums);
|
||||
|
||||
const firstlast = try queries.entityQueryResult(request, queries.loadQuery(.song, .firstlast), .{id});
|
||||
try root.put("firstlast", firstlast);
|
||||
|
|
|
|||
|
|
@ -9,12 +9,24 @@
|
|||
</head>
|
||||
<body>
|
||||
@partial partials/header
|
||||
<div style="text-align:center">
|
||||
<h1>{{.song.song_name}}</h1>
|
||||
<div>{{.song.scrobbles}} scrobbles ({{.song.rank}} place)</div>
|
||||
@partial partials/firstlast_listens(firstlast: .firstlast)
|
||||
<h3>Yearly Performance</h3>
|
||||
@partial partials/timescale(range: .yearly)
|
||||
<h2>Scrobbles</h2>
|
||||
@partial partials/newtable(T: ColumnChoices, table_data: .scrobbles, columns: columns)
|
||||
</div>
|
||||
|
||||
<div style="display:flex;flex-direction:row;justify-content:space-evenly">
|
||||
<div style="display:flex;flex-direction:column;align-self:left">
|
||||
<div>{{.song.scrobbles}} scrobbles ({{.song.rank}} place)</div>
|
||||
@partial partials/firstlast_listens(firstlast: .firstlast)
|
||||
<h3>Yearly Performance</h3>
|
||||
@partial partials/timescale(range: .yearly)
|
||||
<h2>Scrobbles</h2>
|
||||
@partial partials/newtable(T: ColumnChoices, table_data: .scrobbles, columns: columns)
|
||||
</div>
|
||||
<div style="display:flex;flex-direction:column;align-self:right">
|
||||
<h2>Rating</h2>
|
||||
<input type="text">
|
||||
<input type="button">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
109
src/queries.zig
109
src/queries.zig
|
|
@ -23,12 +23,6 @@ pub fn entityQueryResult(request: *jetzig.Request, query: GeneratedQuery, args:
|
|||
return out.get("entity_info").?;
|
||||
}
|
||||
|
||||
//if (query.query_type == .datestreak) {
|
||||
// var out: *jetzig.Data.Value = try Data.object();
|
||||
// const entity = try (try result.next()).?.to(struct { name: []const u8, id: i32, scrobbles: i64, rank: []const u8 }, .{ .dupe = true, .allocator = request.allocator });
|
||||
//
|
||||
//}
|
||||
|
||||
var out: *jetzig.Data.Value = try Data.array();
|
||||
var mapper = result.mapper(UnifiedResult, .{ .dupe = true, .allocator = request.allocator });
|
||||
|
||||
|
|
@ -55,7 +49,7 @@ pub fn entityQueryResult(request: *jetzig.Request, query: GeneratedQuery, args:
|
|||
}
|
||||
|
||||
const EntityType = enum { scrobble, song, album, artist };
|
||||
const QueryTypeEnum = enum { firstlast, timescale, entities, entity_items, appears, entity_info, datestreak, entities_by_name };
|
||||
const QueryTypeEnum = enum { firstlast, timescale, entities, get_songs, get_albums, get_scrobbles, appears, entity_info, datestreak, entities_by_name };
|
||||
|
||||
const GeneratedQuery = struct {
|
||||
entity: EntityType,
|
||||
|
|
@ -65,22 +59,22 @@ const GeneratedQuery = struct {
|
|||
|
||||
const UnifiedResult = struct {
|
||||
album_name: ?[]const u8 = null,
|
||||
album_id: ?i32 = null,
|
||||
album_id: ?i64 = null,
|
||||
song_name: ?[]const u8 = null,
|
||||
song_id: ?i32 = null,
|
||||
song_id: ?i64 = null,
|
||||
artist_name: ?[]const u8 = null,
|
||||
artist_id: ?i32 = null,
|
||||
artist_id: ?i64 = null,
|
||||
scrobbles: ?i64 = null,
|
||||
date: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
const EntityInfoResult = struct {
|
||||
album_name: ?[]const u8 = null,
|
||||
album_id: ?i32 = null,
|
||||
album_id: ?i64 = null,
|
||||
song_name: ?[]const u8 = null,
|
||||
song_id: ?i32 = null,
|
||||
song_id: ?i64 = null,
|
||||
artist_name: ?[]const u8 = null,
|
||||
artist_id: ?i32 = null,
|
||||
artist_id: ?i64 = null,
|
||||
scrobbles: ?i64 = null,
|
||||
date: ?[]const u8 = null,
|
||||
rank: []const u8,
|
||||
|
|
@ -247,20 +241,9 @@ pub fn loadQuery(entity: EntityType, query_type: QueryTypeEnum) GeneratedQuery {
|
|||
},
|
||||
|
||||
.appears =>
|
||||
//.ResultType = AppearsResult,
|
||||
// Not sure how I feel about this one
|
||||
switch (entity) {
|
||||
.scrobble, .album => unreachable,
|
||||
.song =>
|
||||
\\SELECT albums.name AS album_name, albums.id AS album_id, COUNT(scrobbles) AS scrobbles
|
||||
\\FROM artistalbums
|
||||
\\INNER JOIN albums ON albums.id = artistalbums.album_id
|
||||
\\INNER JOIN albumsongs ON albumsongs.album_id = albums.id
|
||||
\\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id
|
||||
\\INNER JOIN albumsongsartists ON albumsongsartists.albumsong_id = albumsongs.id
|
||||
\\WHERE albumsongs.song_id = $1
|
||||
\\GROUP BY albums.id
|
||||
\\ORDER BY scrobbles DESC;
|
||||
,
|
||||
.scrobble, .song, .album => unreachable,
|
||||
.artist =>
|
||||
\\SELECT albums.name AS album_name, albums.id AS album_id, COUNT(scrobbles) AS scrobbles
|
||||
\\FROM artistalbums
|
||||
|
|
@ -274,19 +257,8 @@ pub fn loadQuery(entity: EntityType, query_type: QueryTypeEnum) GeneratedQuery {
|
|||
,
|
||||
},
|
||||
|
||||
.entity_items =>
|
||||
//.ResultType = EntityItemsResult,
|
||||
switch (entity) {
|
||||
.scrobble => unreachable,
|
||||
.song =>
|
||||
\\SELECT songs.name AS song_name, songs.id AS song_id, albums.name AS album_name, albums.id AS album_id, TO_CHAR(scrobbles.datetime, 'YYYY-MM-DD HH24:MI:SS') AS date
|
||||
\\FROM albumsongs
|
||||
\\INNER JOIN albums ON albums.id = albumsongs.album_id
|
||||
\\INNER JOIN songs ON songs.id = albumsongs.song_id
|
||||
\\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id
|
||||
\\WHERE songs.id = $1
|
||||
\\ORDER BY date ASC
|
||||
,
|
||||
.get_songs => switch (entity) {
|
||||
.scrobble, .song => unreachable, // Might be able to use this with SongGroups?
|
||||
.album =>
|
||||
\\SELECT songs.name AS song_name, songs.id AS song_id, COUNT(scrobbles) AS scrobbles
|
||||
\\FROM albumsongs
|
||||
|
|
@ -297,6 +269,34 @@ pub fn loadQuery(entity: EntityType, query_type: QueryTypeEnum) GeneratedQuery {
|
|||
\\ORDER BY scrobbles DESC
|
||||
,
|
||||
.artist =>
|
||||
\\SELECT songs.name AS song_name, songs.id AS song_id, albums.name AS album_name, albums.id AS album_id, COUNT(scrobbles) AS scrobbles
|
||||
\\FROM albumsongs
|
||||
\\INNER JOIN songs ON songs.id = albumsongs.song_id
|
||||
\\INNER JOIN albums ON albums.id = albumsongs.album_id
|
||||
\\INNER JOIN albumsongsartists ON albumsongsartists.albumsong_id = albumsongs.id
|
||||
\\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id
|
||||
\\WHERE albumsongsartists.artist_id = $1
|
||||
\\GROUP BY songs.id, albums.id
|
||||
\\ORDER BY scrobbles DESC
|
||||
,
|
||||
},
|
||||
|
||||
.get_albums =>
|
||||
//.ResultType = EntityItemsResult,
|
||||
switch (entity) {
|
||||
.scrobble, .album => unreachable, // Might be able to use this with ReleaseGroups?
|
||||
.song =>
|
||||
\\SELECT albums.name AS album_name, albums.id AS album_id, COUNT(scrobbles) AS scrobbles
|
||||
\\FROM artistalbums
|
||||
\\INNER JOIN albums ON albums.id = artistalbums.album_id
|
||||
\\INNER JOIN albumsongs ON albumsongs.album_id = albums.id
|
||||
\\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id
|
||||
\\INNER JOIN albumsongsartists ON albumsongsartists.albumsong_id = albumsongs.id
|
||||
\\WHERE albumsongs.song_id = $1
|
||||
\\GROUP BY albums.id
|
||||
\\ORDER BY scrobbles DESC
|
||||
,
|
||||
.artist =>
|
||||
\\SELECT albums.name AS album_name, albums.id AS album_id, COUNT(scrobbles) AS scrobbles
|
||||
\\FROM artistalbums
|
||||
\\INNER JOIN albums ON albums.id = artistalbums.album_id
|
||||
|
|
@ -308,6 +308,37 @@ pub fn loadQuery(entity: EntityType, query_type: QueryTypeEnum) GeneratedQuery {
|
|||
,
|
||||
},
|
||||
|
||||
.get_scrobbles => switch (entity) {
|
||||
.scrobble => unreachable,
|
||||
.song =>
|
||||
\\SELECT songs.name AS song_name, songs.id AS song_id, albums.name AS album_name, albums.id AS album_id, TO_CHAR(scrobbles.datetime, 'YYYY-MM-DD HH24:MI:SS') AS date
|
||||
\\FROM albumsongs
|
||||
\\INNER JOIN albums ON albums.id = albumsongs.album_id
|
||||
\\INNER JOIN songs ON songs.id = albumsongs.song_id
|
||||
\\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id
|
||||
\\WHERE songs.id = $1
|
||||
\\ORDER BY date ASC
|
||||
,
|
||||
.album =>
|
||||
\\SELECT songs.name AS song_name, songs.id AS song_id, albums.name AS album_name, albums.id AS album_id, TO_CHAR(scrobbles.datetime, 'YYYY-MM-DD HH24:MI:SS') AS date
|
||||
\\FROM albumsongs
|
||||
\\INNER JOIN albums ON albums.id = albumsongs.album_id
|
||||
\\INNER JOIN songs ON songs.id = albumsongs.song_id
|
||||
\\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id
|
||||
\\WHERE albums.id = $1
|
||||
\\ORDER BY date ASC
|
||||
,
|
||||
.artist =>
|
||||
\\SELECT songs.name AS song_name, songs.id AS song_id, albums.name AS album_name, albums.id AS album_id, TO_CHAR(scrobbles.datetime, 'YYYY-MM-DD HH24:MI:SS') AS date
|
||||
\\FROM albumsongs
|
||||
\\INNER JOIN albums ON albums.id = albumsongs.album_id
|
||||
\\INNER JOIN songs ON songs.id = albumsongs.song_id
|
||||
\\INNER JOIN scrobbles ON scrobbles.albumsong = albumsongs.id
|
||||
\\WHERE artists.id = $1
|
||||
\\ORDER BY date ASC
|
||||
,
|
||||
},
|
||||
|
||||
.entity_info => switch (entity) {
|
||||
.scrobble => unreachable,
|
||||
.song =>
|
||||
|
|
|
|||
|
|
@ -133,5 +133,5 @@ pub const TableRow = struct {
|
|||
|
||||
pub const HyperlinkData = struct {
|
||||
name: []const u8,
|
||||
id: i32,
|
||||
id: i64,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue