A decentralized music tracking and discovery platform built on AT Protocol 🎵
listenbrainz spotify atproto lastfm musicbrainz scrobbling

update migrations

Changed files
+43 -38
apps
crates
pgpull
src
+34 -34
apps/api/drizzle/0000_greedy_vanisher.sql apps/api/drizzle/0000_polite_pixie.sql
··· 1 CREATE TABLE "album_tracks" ( 2 - "xata_id" text PRIMARY KEY NOT NULL, 3 "album_id" text NOT NULL, 4 "track_id" text NOT NULL, 5 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 8 ); 9 --> statement-breakpoint 10 CREATE TABLE "albums" ( 11 - "xata_id" text PRIMARY KEY NOT NULL, 12 "title" text NOT NULL, 13 "artist" text NOT NULL, 14 "release_date" text, ··· 33 ); 34 --> statement-breakpoint 35 CREATE TABLE "api_keys" ( 36 - "xata_id" text PRIMARY KEY NOT NULL, 37 "name" text NOT NULL, 38 "api_key" text NOT NULL, 39 "shared_secret" text NOT NULL, ··· 45 ); 46 --> statement-breakpoint 47 CREATE TABLE "artist_albums" ( 48 - "xata_id" text PRIMARY KEY NOT NULL, 49 "artist_id" text NOT NULL, 50 "album_id" text NOT NULL, 51 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 54 ); 55 --> statement-breakpoint 56 CREATE TABLE "artist_tracks" ( 57 - "xata_id" text PRIMARY KEY NOT NULL, 58 "artist_id" text NOT NULL, 59 "track_id" text NOT NULL, 60 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 63 ); 64 --> statement-breakpoint 65 CREATE TABLE "artists" ( 66 - "xata_id" text PRIMARY KEY NOT NULL, 67 "name" text NOT NULL, 68 "biography" text, 69 "born" timestamp, ··· 85 ); 86 --> statement-breakpoint 87 CREATE TABLE "dropbox_accounts" ( 88 - "xata_id" text PRIMARY KEY NOT NULL, 89 "email" text NOT NULL, 90 "is_beta_user" boolean DEFAULT false NOT NULL, 91 "user_id" text NOT NULL, ··· 96 ); 97 --> statement-breakpoint 98 CREATE TABLE "dropbox_directories" ( 99 - "xata_id" text PRIMARY KEY NOT NULL, 100 "name" text NOT NULL, 101 "path" text NOT NULL, 102 "parent_id" text, ··· 109 ); 110 --> statement-breakpoint 111 CREATE TABLE "dropbox_paths" ( 112 - "xata_id" text PRIMARY KEY NOT NULL, 113 "path" text NOT NULL, 114 "name" text NOT NULL, 115 "dropbox_id" text NOT NULL, ··· 123 ); 124 --> statement-breakpoint 125 CREATE TABLE "dropbox_tokens" ( 126 - "xata_id" text PRIMARY KEY NOT NULL, 127 "refresh_token" text NOT NULL, 128 "xata_createdat" timestamp DEFAULT now() NOT NULL, 129 "xata_updatedat" timestamp DEFAULT now() NOT NULL 130 ); 131 --> statement-breakpoint 132 CREATE TABLE "dropbox" ( 133 - "xata_id" text PRIMARY KEY NOT NULL, 134 "user_id" text NOT NULL, 135 "dropbox_token_id" text NOT NULL, 136 "xata_version" text NOT NULL, ··· 139 ); 140 --> statement-breakpoint 141 CREATE TABLE "google_drive_accounts" ( 142 - "xata_id" text PRIMARY KEY NOT NULL, 143 "email" text NOT NULL, 144 "is_beta_user" boolean DEFAULT false NOT NULL, 145 "user_id" text NOT NULL, ··· 150 ); 151 --> statement-breakpoint 152 CREATE TABLE "google_drive_directories" ( 153 - "xata_id" text PRIMARY KEY NOT NULL, 154 "name" text NOT NULL, 155 "path" text NOT NULL, 156 "parent_id" text, ··· 163 ); 164 --> statement-breakpoint 165 CREATE TABLE "google_drive_paths" ( 166 - "xata_id" text PRIMARY KEY NOT NULL, 167 "google_drive_id" text NOT NULL, 168 "track_id" text NOT NULL, 169 "name" text NOT NULL, ··· 176 ); 177 --> statement-breakpoint 178 CREATE TABLE "google_drive_tokens" ( 179 - "xata_id" text PRIMARY KEY NOT NULL, 180 "refresh_token" text NOT NULL, 181 "xata_createdat" timestamp DEFAULT now() NOT NULL, 182 "xata_updatedat" timestamp DEFAULT now() NOT NULL 183 ); 184 --> statement-breakpoint 185 CREATE TABLE "google_drive" ( 186 - "xata_id" text PRIMARY KEY NOT NULL, 187 "google_drive_token_id" text NOT NULL, 188 "user_id" text NOT NULL, 189 "xata_version" text NOT NULL, ··· 192 ); 193 --> statement-breakpoint 194 CREATE TABLE "loved_tracks" ( 195 - "xata_id" text PRIMARY KEY NOT NULL, 196 "user_id" text NOT NULL, 197 "track_id" text NOT NULL, 198 "uri" text, ··· 201 ); 202 --> statement-breakpoint 203 CREATE TABLE "playlist_tracks" ( 204 - "xata_id" text PRIMARY KEY NOT NULL, 205 "playlist_id" text NOT NULL, 206 "track_id" text NOT NULL, 207 "xata_createdat" timestamp DEFAULT now() NOT NULL 208 ); 209 --> statement-breakpoint 210 CREATE TABLE "playlists" ( 211 - "xata_id" text PRIMARY KEY NOT NULL, 212 "name" text NOT NULL, 213 "picture" text, 214 "description" text, ··· 223 ); 224 --> statement-breakpoint 225 CREATE TABLE "profile_shouts" ( 226 - "xata_id" text PRIMARY KEY NOT NULL, 227 "user_id" text NOT NULL, 228 "shout_id" text NOT NULL, 229 "xata_createdat" timestamp DEFAULT now() NOT NULL 230 ); 231 --> statement-breakpoint 232 CREATE TABLE "queue_tracks" ( 233 - "xata_id" text PRIMARY KEY NOT NULL, 234 "user_id" text NOT NULL, 235 "track_id" text NOT NULL, 236 "position" integer NOT NULL, ··· 241 ); 242 --> statement-breakpoint 243 CREATE TABLE "scrobbles" ( 244 - "xata_id" text PRIMARY KEY NOT NULL, 245 "user_id" text, 246 "track_id" text, 247 "album_id" text, ··· 255 ); 256 --> statement-breakpoint 257 CREATE TABLE "shout_likes" ( 258 - "xata_id" text PRIMARY KEY NOT NULL, 259 "user_id" text NOT NULL, 260 "shout_id" text NOT NULL, 261 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 264 ); 265 --> statement-breakpoint 266 CREATE TABLE "shout_reports" ( 267 - "xata_id" text PRIMARY KEY NOT NULL, 268 "user_id" text NOT NULL, 269 "shout_id" text NOT NULL, 270 "xata_createdat" timestamp DEFAULT now() NOT NULL 271 ); 272 --> statement-breakpoint 273 CREATE TABLE "shouts" ( 274 - "xata_id" text PRIMARY KEY NOT NULL, 275 "content" text NOT NULL, 276 "track_id" text, 277 "artist_id" text, ··· 286 ); 287 --> statement-breakpoint 288 CREATE TABLE "spotify_accounts" ( 289 - "xata_id" text PRIMARY KEY NOT NULL, 290 "xata_version" integer NOT NULL, 291 "email" text NOT NULL, 292 "user_id" text NOT NULL, ··· 296 ); 297 --> statement-breakpoint 298 CREATE TABLE "spotify_tokens" ( 299 - "xata_id" text PRIMARY KEY NOT NULL, 300 "xata_version" integer NOT NULL, 301 "access_token" text NOT NULL, 302 "refresh_token" text NOT NULL, ··· 306 ); 307 --> statement-breakpoint 308 CREATE TABLE "tracks" ( 309 - "xata_id" text PRIMARY KEY NOT NULL, 310 "title" text NOT NULL, 311 "artist" text NOT NULL, 312 "album_artist" text NOT NULL, ··· 342 ); 343 --> statement-breakpoint 344 CREATE TABLE "user_albums" ( 345 - "xata_id" text PRIMARY KEY NOT NULL, 346 "user_id" text NOT NULL, 347 "album_id" text NOT NULL, 348 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 354 ); 355 --> statement-breakpoint 356 CREATE TABLE "user_artists" ( 357 - "xata_id" text PRIMARY KEY NOT NULL, 358 "user_id" text NOT NULL, 359 "artist_id" text NOT NULL, 360 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 366 ); 367 --> statement-breakpoint 368 CREATE TABLE "user_playlists" ( 369 - "xata_id" text PRIMARY KEY NOT NULL, 370 "user_id" text NOT NULL, 371 "playlist_id" text NOT NULL, 372 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 375 ); 376 --> statement-breakpoint 377 CREATE TABLE "user_tracks" ( 378 - "xata_id" text PRIMARY KEY NOT NULL, 379 "user_id" text NOT NULL, 380 "track_id" text NOT NULL, 381 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 387 ); 388 --> statement-breakpoint 389 CREATE TABLE "users" ( 390 - "xata_id" text PRIMARY KEY NOT NULL, 391 "did" text NOT NULL, 392 "display_name" text, 393 "handle" text NOT NULL, ··· 400 ); 401 --> statement-breakpoint 402 CREATE TABLE "webscrobblers" ( 403 - "xata_id" text PRIMARY KEY NOT NULL, 404 "name" text NOT NULL, 405 "uuid" text NOT NULL, 406 "description" text,
··· 1 CREATE TABLE "album_tracks" ( 2 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 3 "album_id" text NOT NULL, 4 "track_id" text NOT NULL, 5 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 8 ); 9 --> statement-breakpoint 10 CREATE TABLE "albums" ( 11 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 12 "title" text NOT NULL, 13 "artist" text NOT NULL, 14 "release_date" text, ··· 33 ); 34 --> statement-breakpoint 35 CREATE TABLE "api_keys" ( 36 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 37 "name" text NOT NULL, 38 "api_key" text NOT NULL, 39 "shared_secret" text NOT NULL, ··· 45 ); 46 --> statement-breakpoint 47 CREATE TABLE "artist_albums" ( 48 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 49 "artist_id" text NOT NULL, 50 "album_id" text NOT NULL, 51 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 54 ); 55 --> statement-breakpoint 56 CREATE TABLE "artist_tracks" ( 57 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 58 "artist_id" text NOT NULL, 59 "track_id" text NOT NULL, 60 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 63 ); 64 --> statement-breakpoint 65 CREATE TABLE "artists" ( 66 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 67 "name" text NOT NULL, 68 "biography" text, 69 "born" timestamp, ··· 85 ); 86 --> statement-breakpoint 87 CREATE TABLE "dropbox_accounts" ( 88 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 89 "email" text NOT NULL, 90 "is_beta_user" boolean DEFAULT false NOT NULL, 91 "user_id" text NOT NULL, ··· 96 ); 97 --> statement-breakpoint 98 CREATE TABLE "dropbox_directories" ( 99 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 100 "name" text NOT NULL, 101 "path" text NOT NULL, 102 "parent_id" text, ··· 109 ); 110 --> statement-breakpoint 111 CREATE TABLE "dropbox_paths" ( 112 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 113 "path" text NOT NULL, 114 "name" text NOT NULL, 115 "dropbox_id" text NOT NULL, ··· 123 ); 124 --> statement-breakpoint 125 CREATE TABLE "dropbox_tokens" ( 126 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 127 "refresh_token" text NOT NULL, 128 "xata_createdat" timestamp DEFAULT now() NOT NULL, 129 "xata_updatedat" timestamp DEFAULT now() NOT NULL 130 ); 131 --> statement-breakpoint 132 CREATE TABLE "dropbox" ( 133 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 134 "user_id" text NOT NULL, 135 "dropbox_token_id" text NOT NULL, 136 "xata_version" text NOT NULL, ··· 139 ); 140 --> statement-breakpoint 141 CREATE TABLE "google_drive_accounts" ( 142 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 143 "email" text NOT NULL, 144 "is_beta_user" boolean DEFAULT false NOT NULL, 145 "user_id" text NOT NULL, ··· 150 ); 151 --> statement-breakpoint 152 CREATE TABLE "google_drive_directories" ( 153 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 154 "name" text NOT NULL, 155 "path" text NOT NULL, 156 "parent_id" text, ··· 163 ); 164 --> statement-breakpoint 165 CREATE TABLE "google_drive_paths" ( 166 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 167 "google_drive_id" text NOT NULL, 168 "track_id" text NOT NULL, 169 "name" text NOT NULL, ··· 176 ); 177 --> statement-breakpoint 178 CREATE TABLE "google_drive_tokens" ( 179 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 180 "refresh_token" text NOT NULL, 181 "xata_createdat" timestamp DEFAULT now() NOT NULL, 182 "xata_updatedat" timestamp DEFAULT now() NOT NULL 183 ); 184 --> statement-breakpoint 185 CREATE TABLE "google_drive" ( 186 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 187 "google_drive_token_id" text NOT NULL, 188 "user_id" text NOT NULL, 189 "xata_version" text NOT NULL, ··· 192 ); 193 --> statement-breakpoint 194 CREATE TABLE "loved_tracks" ( 195 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 196 "user_id" text NOT NULL, 197 "track_id" text NOT NULL, 198 "uri" text, ··· 201 ); 202 --> statement-breakpoint 203 CREATE TABLE "playlist_tracks" ( 204 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 205 "playlist_id" text NOT NULL, 206 "track_id" text NOT NULL, 207 "xata_createdat" timestamp DEFAULT now() NOT NULL 208 ); 209 --> statement-breakpoint 210 CREATE TABLE "playlists" ( 211 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 212 "name" text NOT NULL, 213 "picture" text, 214 "description" text, ··· 223 ); 224 --> statement-breakpoint 225 CREATE TABLE "profile_shouts" ( 226 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 227 "user_id" text NOT NULL, 228 "shout_id" text NOT NULL, 229 "xata_createdat" timestamp DEFAULT now() NOT NULL 230 ); 231 --> statement-breakpoint 232 CREATE TABLE "queue_tracks" ( 233 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 234 "user_id" text NOT NULL, 235 "track_id" text NOT NULL, 236 "position" integer NOT NULL, ··· 241 ); 242 --> statement-breakpoint 243 CREATE TABLE "scrobbles" ( 244 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 245 "user_id" text, 246 "track_id" text, 247 "album_id" text, ··· 255 ); 256 --> statement-breakpoint 257 CREATE TABLE "shout_likes" ( 258 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 259 "user_id" text NOT NULL, 260 "shout_id" text NOT NULL, 261 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 264 ); 265 --> statement-breakpoint 266 CREATE TABLE "shout_reports" ( 267 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 268 "user_id" text NOT NULL, 269 "shout_id" text NOT NULL, 270 "xata_createdat" timestamp DEFAULT now() NOT NULL 271 ); 272 --> statement-breakpoint 273 CREATE TABLE "shouts" ( 274 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 275 "content" text NOT NULL, 276 "track_id" text, 277 "artist_id" text, ··· 286 ); 287 --> statement-breakpoint 288 CREATE TABLE "spotify_accounts" ( 289 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 290 "xata_version" integer NOT NULL, 291 "email" text NOT NULL, 292 "user_id" text NOT NULL, ··· 296 ); 297 --> statement-breakpoint 298 CREATE TABLE "spotify_tokens" ( 299 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 300 "xata_version" integer NOT NULL, 301 "access_token" text NOT NULL, 302 "refresh_token" text NOT NULL, ··· 306 ); 307 --> statement-breakpoint 308 CREATE TABLE "tracks" ( 309 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 310 "title" text NOT NULL, 311 "artist" text NOT NULL, 312 "album_artist" text NOT NULL, ··· 342 ); 343 --> statement-breakpoint 344 CREATE TABLE "user_albums" ( 345 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 346 "user_id" text NOT NULL, 347 "album_id" text NOT NULL, 348 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 354 ); 355 --> statement-breakpoint 356 CREATE TABLE "user_artists" ( 357 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 358 "user_id" text NOT NULL, 359 "artist_id" text NOT NULL, 360 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 366 ); 367 --> statement-breakpoint 368 CREATE TABLE "user_playlists" ( 369 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 370 "user_id" text NOT NULL, 371 "playlist_id" text NOT NULL, 372 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 375 ); 376 --> statement-breakpoint 377 CREATE TABLE "user_tracks" ( 378 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 379 "user_id" text NOT NULL, 380 "track_id" text NOT NULL, 381 "xata_createdat" timestamp DEFAULT now() NOT NULL, ··· 387 ); 388 --> statement-breakpoint 389 CREATE TABLE "users" ( 390 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 391 "did" text NOT NULL, 392 "display_name" text, 393 "handle" text NOT NULL, ··· 400 ); 401 --> statement-breakpoint 402 CREATE TABLE "webscrobblers" ( 403 + "xata_id" text PRIMARY KEY DEFAULT xata_id(), 404 "name" text NOT NULL, 405 "uuid" text NOT NULL, 406 "description" text,
+1 -1
apps/api/drizzle/meta/0000_snapshot.json
··· 1 { 2 - "id": "97b0b357-40d7-42b5-ab53-2738bd804a2c", 3 "prevId": "00000000-0000-0000-0000-000000000000", 4 "version": "7", 5 "dialect": "postgresql",
··· 1 { 2 + "id": "f7f59d87-3fa3-4146-91b5-692a483d2abc", 3 "prevId": "00000000-0000-0000-0000-000000000000", 4 "version": "7", 5 "dialect": "postgresql",
+2 -2
apps/api/drizzle/meta/_journal.json
··· 5 { 6 "idx": 0, 7 "version": "7", 8 - "when": 1759736561936, 9 - "tag": "0000_greedy_vanisher", 10 "breakpoints": true 11 } 12 ]
··· 5 { 6 "idx": 0, 7 "version": "7", 8 + "when": 1759738835464, 9 + "tag": "0000_polite_pixie", 10 "breakpoints": true 11 } 12 ]
+6 -1
crates/pgpull/src/lib.rs
··· 239 240 for loved_track in &loved_tracks { 241 tracing::info!(user_id = %loved_track.user_id.cyan(), track_id = %loved_track.track_id.magenta(), i = %i.magenta(), total = %total_loved_tracks.magenta(), "Inserting loved track"); 242 - repo::loved_track::insert_loved_track(&dest_pool_clone, loved_track).await?; 243 i += 1; 244 } 245 }
··· 239 240 for loved_track in &loved_tracks { 241 tracing::info!(user_id = %loved_track.user_id.cyan(), track_id = %loved_track.track_id.magenta(), i = %i.magenta(), total = %total_loved_tracks.magenta(), "Inserting loved track"); 242 + match repo::loved_track::insert_loved_track(&dest_pool_clone, loved_track).await { 243 + Ok(_) => {} 244 + Err(e) => { 245 + tracing::error!(error = %e, "Failed to insert loved track"); 246 + } 247 + } 248 i += 1; 249 } 250 }