rendered paste body#define _GNU_SOURCE#include <stdio.h>#include <string.h>#include <libgen.h>#include <sys/stat.h>#include <errno.h>#include <stdio.h>#include "library.h"#include "album.h"#include "lastfm.h"#include "helper.h"#include <dbi/dbi.h>#include <semaphore.h>#include "database.h"/* Library global mutex */extern sem_t mutex;extern dbi_conn DB_conn;int LIBRARY_get_artist_name_from_album(long long album_id, char **empty){ char *buffer=NULL; const char *err=NULL; dbi_result result=NULL; /* MUTEX */ sem_wait(&mutex); result = dbi_conn_queryf(DB_conn,"SELECT Artist.name \ FROM Artist \ JOIN Album_Artist ON Artist.id = Album_Artist.artist_id \ JOIN Album ON Album.id = Album_Artist.album_id \ WHERE Album.id=%llu",album_id); if(result == NULL){ dbi_conn_error(DB_conn,&err); printf("artist.c:35:%s\n",err); }else if(dbi_result_first_row(result)){ buffer = DB_strdup(result,1); dbi_result_free(result); }else{ printf("LIBRARY_get_artist_name:%llu\n",album_id); dbi_result_free(result); } sem_post(&mutex); *empty = buffer; return 0;}int LIBRARY_free_artist_metadata(LIBRARY_artist_metadata *l){ int i,j; if(l == NULL)return 1; for(i=0;i<l->album_count;i++){ for(j=0;j<l->album[i]->track_count;j++){ free(l->album[i]->tracks[j]); } free(l->album[i]->tracks); free(l->album[i]); } free(l->album); free(l); return 0;}int LIBRARY_free_artist_metadata_array(LIBRARY_artist_metadata **l,long long size){ int i,j,k; if(l == NULL)return 1; for(i=0;i<size;i++){ for(j=0;j<l[i]->album_count;j++){ for(k=0;k<l[i]->album[j]->track_count;k++){ free(l[i]->album[j]->tracks[k]); } free(l[i]->album[j]->tracks); free(l[i]->album[j]); } free(l[i]->album); free(l[i]); } free(l); return 0;}void LIBRARY_print_artist_metadata(LIBRARY_artist_metadata **lib,long long size){ int i,j,k; printf("LIBRARY_print_artist_metadata: Size = %lli\n",size); for(i=0;i<size;i++){ printf("[%4lli] %s\n",lib[i]->id,lib[i]->name); for(j=0;j<lib[i]->album_count;j++){ printf(" +--[%4lli] %s\n",lib[i]->album[j]->id, lib[i]->album[j]->name); for(k=0;k<lib[i]->album[j]->track_count;k++){ printf(" |--[%5lli] %s\n", lib[i]->album[j]->tracks[k]->id, lib[i]->album[j]->tracks[k]->name); } } }}long long LIBRARY_get_artist(LIBRARY_artist_metadata **lib, long long artist_id){ dbi_result result,sub_result; long long size; int i,j; LIBRARY_album_metadata **alib; LIBRARY_track_metadata *tptr; LIBRARY_artist_metadata *artist; /* MUTEX */ sem_wait(&mutex); printf("LIBRARY_get_artist: %llu\n",artist_id); result = dbi_conn_queryf(DB_conn, "SELECT Artist.id,Artist.name \ FROM Artist \ JOIN Album_Artist ON Artist.id = Album_Artist.artist_id \ JOIN Album ON Album_Artist.album_id = Album.id \ WHERE Album.VA=0 AND Artist.id=%llu \ GROUP BY Artist.name,Artist.id", artist_id); if(dbi_result_next_row(result)){ artist = malloc(sizeof(LIBRARY_artist_metadata)); artist->id = dbi_result_get_ulonglong_idx(result,1); DB_strcpy(artist->name,result,2); printf("type=%u\n",dbi_result_get_field_type_idx(result,2)); }else{ sem_post(&mutex); return 0; } dbi_result_free(result); result = dbi_conn_queryf(DB_conn, "SELECT Album.id,Album.name \ FROM Album \ JOIN Album_Artist ON Album_Artist.album_id = Album.id \ JOIN Artist ON Artist.id = Album_Artist.artist_id \ WHERE Artist.id=%llu \ AND Album.VA=0 \ ORDER BY Album.name",artist_id); size = dbi_result_get_numrows(result); artist->album_count = size; printf("album_count = %lli\n",size); artist->album = malloc(size*sizeof(LIBRARY_album_metadata*)); alib = artist->album; i=0;j=0; while (dbi_result_next_row(result)) { alib[i] = malloc(sizeof(LIBRARY_album_metadata)); alib[i]->id = dbi_result_get_ulonglong_idx(result,1); DB_strcpy(alib[i]->name,result,2); alib[i]->artist_id = artist_id; alib[i]->va = 0;// printf("alib[i]->name = %s\n",alib[i]->name); sub_result = dbi_conn_queryf(DB_conn, "SELECT id,year,length,track,title \ FROM Tags \ WHERE album=%llu AND artist=%llu \ ORDER BY track",alib[i]->id,artist_id); alib[i]->track_count = dbi_result_get_numrows(sub_result); alib[i]->length =0; alib[i]->tracks = malloc(alib[i]->track_count *sizeof(LIBRARY_track_metadata)); j=0; while (dbi_result_next_row(sub_result)) { alib[i]->tracks[j] = malloc(sizeof(LIBRARY_track_metadata)); tptr = alib[i]->tracks[j]; tptr->id = dbi_result_get_ulonglong_idx(sub_result,1); tptr->year = dbi_result_get_int_idx(sub_result,2); tptr->length = dbi_result_get_int_idx(sub_result,3); tptr->track= dbi_result_get_short_idx(sub_result,4); DB_strcpy(tptr->name,sub_result,5); tptr->artist_id = 0; tptr->album_id = 0; alib[i]->length += tptr->length; j++; } dbi_result_free(sub_result); i++; } dbi_result_free(result); *lib = artist; sem_post(&mutex); return size;} /* Do not return artists that only appear in Various Artist albums*/long long LIBRARY_get_all_artists(LIBRARY_artist_metadata ***lib){ long long size; int i,j,k; int album_count,track_count; unsigned long long album_id,artist_id,track_id; LIBRARY_album_metadata *album_ptr; LIBRARY_track_metadata *track_ptr; struct timespec t1,t2,t3,t4,t5,t6; dbi_result result,sub_result,temp_result; /* MUTEX */ sem_wait(&mutex); result = dbi_conn_query(DB_conn, "SELECT Artist.name,Artist.id FROM " "Artist " "JOIN Album_Artist ON Artist.id = Album_Artist.artist_id " "JOIN Album ON Album_Artist.album_id = Album.id " "WHERE Album.VA!=1 " "GROUP BY Artist.id,Artist.name " "ORDER BY Artist.name"); size = dbi_result_get_numrows(result); printf("LIBRARY_get_all_artists: artist_count = %llu\n",size); /* Allocate this massive buffer */ *lib = malloc(size*sizeof(LIBRARY_artist_metadata*)); LIBRARY_artist_metadata **artists_library = *lib; /* Copy out the data */ for(i=0;dbi_result_next_row(result);i++){ clock_gettime(CLOCK_REALTIME,&t1); artists_library[i] = malloc(sizeof(LIBRARY_artist_metadata)); DB_strcpy(artists_library[i]->name,result,1); artist_id = dbi_result_get_ulonglong_idx(result,2); clock_gettime(CLOCK_REALTIME,&t5); sub_result = dbi_conn_queryf(DB_conn,"SELECT Album.id,name " "FROM Album_Artist " "JOIN Album ON Album.id = Album_Artist.album_id " "JOIN Tags ON Tags.album = Album_Artist.album_id " "WHERE artist_id=%llu AND VA!=1 " "GROUP BY Album.id,name",artist_id); album_count = dbi_result_get_numrows(sub_result); clock_gettime(CLOCK_REALTIME,&t6); printf("Album Ftook = %5lius\n", ((t6.tv_sec - t5.tv_sec)*1000000)+ ((t6.tv_nsec- t5.tv_nsec)/1000)); artists_library[i]->id = artist_id; artists_library[i]->album_count = album_count; artists_library[i]->va_album_count = 0; artists_library[i]->va_album = NULL; artists_library[i]->album = malloc(album_count* sizeof(LIBRARY_album_metadata*)); for(j=0;dbi_result_next_row(sub_result);j++){ clock_gettime(CLOCK_REALTIME,&t3); artists_library[i]->album[j] = malloc(sizeof(LIBRARY_album_metadata)); album_ptr = artists_library[i]->album[j]; album_id = dbi_result_get_ulonglong_idx(sub_result,1); DB_strcpy(album_ptr->name,sub_result,2); album_ptr->length = 0; album_ptr->va = 0; temp_result = dbi_conn_queryf(DB_conn,"SELECT " "id,title,length,track FROM Tags " "WHERE album=%llu AND artist=%llu " "ORDER BY track",album_id,artist_id); track_count = dbi_result_get_numrows(temp_result); album_ptr->id = album_id; album_ptr->artist_id = artist_id; album_ptr->track_count = track_count; album_ptr->tracks = malloc(track_count * sizeof(LIBRARY_track_metadata*)); for(k=0;dbi_result_next_row(temp_result);k++){ album_ptr->tracks[k] = malloc(sizeof(LIBRARY_track_metadata)); track_ptr = album_ptr->tracks[k]; track_id = dbi_result_get_ulonglong_idx(temp_result,1); DB_strcpy(track_ptr->name,temp_result,2); track_ptr->length = dbi_result_get_short_idx(temp_result,3); track_ptr->track = dbi_result_get_short_idx(temp_result,4); album_ptr->length += track_ptr->length; track_ptr->id = track_id; track_ptr->artist_id = 0; track_ptr->album_id = 0; } // Tracks dbi_result_free(temp_result); clock_gettime(CLOCK_REALTIME,&t4); printf("Album took = %5lius\n", ((t4.tv_sec - t3.tv_sec)*1000000)+ ((t4.tv_nsec-t3.tv_nsec)/1000)); } // Album dbi_result_free(sub_result); clock_gettime(CLOCK_REALTIME,&t2); printf("Artist took = %5lius\n", ((t2.tv_sec - t1.tv_sec)*1000000)+ ((t2.tv_nsec-t1.tv_nsec)/1000)); }// Artist dbi_result_free(result); sem_post(&mutex); return size;}int LIBRARY_add_artist_info(long long artist_id, LASTFM_ARTIST_INFO *a){ char *quote=NULL; dbi_result result,sub_result; const char *error; long long smallsum; long long sartist_id; int rv; int i; if(a== NULL)return 1; if(artist_id == 0) return 1; /* MUTEX */ sem_wait(&mutex); if(a->image_size!= 0){ rv = dbi_conn_quote_binary_copy(DB_conn,a->image, a->image_size,(unsigned char **)"e); smallsum = HELPER_hash(a->image,a->image_size); if(rv == 0){ if(quote)free(quote); dbi_conn_error(DB_conn,&error); fprintf(stderr,"LIBRARY_add_artist_info:Quote Error:%s\n",error); sem_post(&mutex); return 1; } result = dbi_conn_queryf(DB_conn,"INSERT INTO ArtistArt \ (artist_id,data,smallsum) VALUES(%llu,%s,%llu)", artist_id,quote,smallsum); free(quote); if(result == NULL){ dbi_conn_error(DB_conn,&error); fprintf(stderr,"LIBRARY_add_artist_info:Add Art:%s\n",error); sem_post(&mutex); return 1; } dbi_result_free(result); } if(a->similar){ for(i=0;a->similar[i];i++){ sartist_id = HELPER_hash((unsigned char *)a->similar[i],0); /* Add the relationship to the SimilarArtist table */ sub_result = dbi_conn_queryf(DB_conn,"INSERT \ IGNORE INTO SimilarArtist (artist_id,sartist_id) \ VALUES(%llu,%llu)",artist_id,sartist_id); if(sub_result == NULL){ dbi_conn_error(DB_conn,&error); printf("LIBRARY_add_artist_info:Add Similar:%s\n",error); sem_post(&mutex); return 1; } dbi_result_free(sub_result); } } if(a->summary){ rv = dbi_conn_quote_string_copy(DB_conn,a->summary,"e); result = dbi_conn_queryf(DB_conn,"UPDATE Artist \ SET summary=%s WHERE id=%llu",quote,artist_id); free(quote); if(result == NULL){ dbi_conn_error(DB_conn,&error); printf("LIBRARY_add_artist_info:Add Summary:%s\n",error); sem_post(&mutex); return 1; } dbi_result_free(result); } sem_post(&mutex); return 0;}void _LIBRARY_delete_artist(long long old_id){ dbi_result result=NULL; result = dbi_conn_queryf(DB_conn,"DELETE \ FROM Album_Artist WHERE artist_id=%llu",old_id); dbi_result_free(result); result = dbi_conn_queryf(DB_conn,"DELETE \ FROM SimilarArtist WHERE artist_id=%llu",old_id); dbi_result_free(result); result = dbi_conn_queryf(DB_conn,"DELETE \ FROM ArtistArt WHERE artist_id=%llu",old_id); dbi_result_free(result); result = dbi_conn_queryf(DB_conn,"DELETE \ FROM Artist WHERE id=%llu",old_id); dbi_result_free(result);}long long _LIBRARY_rename_artist(long long tag_id, long long album_id, long long old_id, const char *old, const char *new){ long long new_id; long long tag_count=0; char *quote_new= NULL; dbi_result result=NULL; printf("LIBRARY_rename_artist:'%s' -> '%s'",old,new); /* Compute id for new artist name */ new_id = HELPER_hash((unsigned char *)new,0); /* Check if that id already exists */ result = dbi_conn_queryf(DB_conn,"SELECT id \ FROM Artist \ WHERE id=%llu",new_id); /* If its a new artist - add to Artist table */ if(!dbi_result_first_row(result)){ dbi_result_free(result); dbi_conn_quote_string_copy(DB_conn,new,"e_new); result = dbi_conn_queryf(DB_conn,"INSERT INTO Artist \ (id,name) VALUES(%llu,%s)",new_id,quote_new); free(quote_new); dbi_result_free(result); }else dbi_result_free(result); /* Update Tag */ result = dbi_conn_queryf(DB_conn,"UPDATE Tags \ SET artist=%llu WHERE id=%llu",new_id,tag_id); dbi_result_free(result); /* Update relations if necessary in Album_Artist table */ result = dbi_conn_queryf(DB_conn,"SELECT artist_id,album_id \ FROM Album_Artist \ WHERE artist_id=%llu AND album_id=%llu", new_id,album_id); if(!dbi_result_first_row(result)){ dbi_result_free(result); result = dbi_conn_queryf(DB_conn,"INSERT INTO Album_Artist \ (artist_id,album_id) VALUES(%llu,%llu)", new_id,album_id); dbi_result_free(result); }else dbi_result_free(result); /* Is the Album_Artist relationship still needed for the old artist */ result = dbi_conn_queryf(DB_conn,"SELECT COUNT(id) \ FROM Tags \ WHERE artist=%llu AND album=%llu",old_id,album_id); dbi_result_first_row(result); tag_count = dbi_result_get_longlong_idx(result,1); dbi_result_free(result); if(tag_count == 0){ result = dbi_conn_queryf(DB_conn,"DELETE \ FROM Album_Artist \ WHERE album_id=%llu AND artist_id=%llu", album_id,old_id); dbi_result_free(result); } /* Check if there are any tags now that belong to the old artist * - Delete old artist entry if necessary */ result = dbi_conn_queryf(DB_conn,"SELECT COUNT(id) \ FROM Tags \ WHERE artist=%llu",old_id); dbi_result_first_row(result); tag_count = dbi_result_get_longlong_idx(result,1); dbi_result_free(result); if(tag_count == 0) { _LIBRARY_delete_artist(old_id); } return new_id;}