All pastes #1816062 Raw Edit

C

public c v1 · immutable
#1816062 ·published 2010-02-28 21:52 UTC
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 **)&quote);		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,&quote);		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,&quote_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;}