add delete to gdbm

This commit is contained in:
Ron Pedde 2004-03-14 00:47:42 +00:00
parent acfcde0dda
commit 59059a48f3
3 changed files with 149 additions and 17 deletions

View File

@ -1,3 +1,7 @@
2004-03-13 Ron Pedde <ron@pedde.com>
* src/mp3-scanner.c: fix static playlists - untracked bug
2004-03-10 Ron Pedde <ron@pedde.com> 2004-03-10 Ron Pedde <ron@pedde.com>
* src/daap.c: make "smart" playlists show the smart playlist icon * src/daap.c: make "smart" playlists show the smart playlist icon

View File

@ -32,6 +32,7 @@
#include "err.h" #include "err.h"
#include "mp3-scanner.h" #include "mp3-scanner.h"
#include "playlist.h" #include "playlist.h"
#include "redblack.h"
#define DB_VERSION 1 #define DB_VERSION 1
#define STRLEN(a) (a) ? strlen((a)) + 1 : 1 #define STRLEN(a) (a) ? strlen((a)) + 1 : 1
@ -103,8 +104,8 @@ DB_PLAYLIST db_playlists;
pthread_rwlock_t db_rwlock; /* OSX doesn't have PTHREAD_RWLOCK_INITIALIZER */ pthread_rwlock_t db_rwlock; /* OSX doesn't have PTHREAD_RWLOCK_INITIALIZER */
pthread_once_t db_initlock=PTHREAD_ONCE_INIT; pthread_once_t db_initlock=PTHREAD_ONCE_INIT;
MP3RECORD db_enum_helper; MP3RECORD db_enum_helper;
GDBM_FILE db_songs; GDBM_FILE db_songs;
struct rbtree *db_removed;
/* /*
* Forwards * Forwards
@ -117,6 +118,7 @@ int db_init(char *parameters);
int db_deinit(void); int db_deinit(void);
int db_version(void); int db_version(void);
int db_add(MP3FILE *mp3file); int db_add(MP3FILE *mp3file);
int db_delete(int id);
int db_add_playlist(unsigned int playlistid, char *name, int is_smart); int db_add_playlist(unsigned int playlistid, char *name, int is_smart);
int db_add_playlist_song(unsigned int playlistid, unsigned int itemid); int db_add_playlist_song(unsigned int playlistid, unsigned int itemid);
int db_unpackrecord(datum *pdatum, MP3FILE *pmp3); int db_unpackrecord(datum *pdatum, MP3FILE *pmp3);
@ -143,6 +145,19 @@ char *db_get_playlist_name(int playlistid);
MP3FILE *db_find(int id); MP3FILE *db_find(int id);
void db_freefile(MP3FILE *pmp3); void db_freefile(MP3FILE *pmp3);
int db_compare_rb_nodes(const void *pa, const void *pb, const void *cfg);
/*
* db_compare_rb_nodes
*
* compare redblack nodes, which are just ints
*/
int db_compare_rb_nodes(const void *pa, const void *pb, const void *cfg) {
if(*(int*)pa < *(int *)pb) return -1;
if(*(int*)pb < *(int *)pa) return 1;
return 0;
}
/* /*
* db_init_once * db_init_once
@ -162,13 +177,17 @@ void db_init_once(void) {
*/ */
int db_init(char *parameters) { int db_init(char *parameters) {
MP3FILE mp3file; MP3FILE mp3file;
datum tmp_key,tmp_nextkey,song_data; datum tmp_key,tmp_nextkey,song_data;
char db_path[PATH_MAX + 1]; char db_path[PATH_MAX + 1];
if(pthread_once(&db_initlock,db_init_once)) if(pthread_once(&db_initlock,db_init_once))
return -1; return -1;
if((db_removed=rbinit(db_compare_rb_nodes,NULL)) == NULL) {
errno=ENOMEM;
return -1;
}
pl_register(); pl_register();
snprintf(db_path,sizeof(db_path),"%s/%s",parameters,"songs.gdb"); snprintf(db_path,sizeof(db_path),"%s/%s",parameters,"songs.gdb");
@ -191,6 +210,12 @@ int db_init(char *parameters) {
MEMNOTIFY(tmp_key.dptr); MEMNOTIFY(tmp_key.dptr);
while(tmp_key.dptr) { while(tmp_key.dptr) {
/* Add it to the rbtree */
if(!rbsearch((void*)tmp_key.dptr,db_removed)) {
errno=ENOMEM;
return -1;
}
/* Fetch that key */ /* Fetch that key */
song_data=gdbm_fetch(db_songs,tmp_key); song_data=gdbm_fetch(db_songs,tmp_key);
MEMNOTIFY(song_data.dptr); MEMNOTIFY(song_data.dptr);
@ -205,7 +230,7 @@ int db_init(char *parameters) {
tmp_nextkey=gdbm_nextkey(db_songs,tmp_key); tmp_nextkey=gdbm_nextkey(db_songs,tmp_key);
MEMNOTIFY(tmp_nextkey.dptr); MEMNOTIFY(tmp_nextkey.dptr);
free(tmp_key.dptr); // free(tmp_key.dptr); /* we'll free it in update mode */
tmp_key=tmp_nextkey; tmp_key=tmp_nextkey;
db_song_count++; db_song_count++;
} }
@ -268,7 +293,19 @@ int db_start_initial_update(void) {
* Take the db out of bulk import mode * Take the db out of bulk import mode
*/ */
int db_end_initial_update(void) { int db_end_initial_update(void) {
const void *val;
int inode;
db_update_mode=0; db_update_mode=0;
DPRINTF(ERR_DEBUG,"Initial update over. Removing stale items\n");
for(val=rblookup(RB_LUFIRST,NULL,db_removed); val != NULL; val=rblookup(RB_LUNEXT,val,db_removed)) {
db_delete(*((int*)val));
free(val);
}
rbdestroy(db_removed);
return 0; return 0;
} }
@ -349,7 +386,7 @@ int db_add_playlist_song(unsigned int playlistid, unsigned int itemid) {
pnew->id=itemid; pnew->id=itemid;
pnew->next=NULL; pnew->next=NULL;
DPRINTF(ERR_DEBUG,"Adding new playlist item\n"); DPRINTF(ERR_DEBUG,"Adding item %d to %d\n",itemid,playlistid);
if((err=pthread_rwlock_wrlock(&db_rwlock))) { if((err=pthread_rwlock_wrlock(&db_rwlock))) {
DPRINTF(ERR_WARN,"cannot lock wrlock in db_add\n"); DPRINTF(ERR_WARN,"cannot lock wrlock in db_add\n");
@ -372,7 +409,9 @@ int db_add_playlist_song(unsigned int playlistid, unsigned int itemid) {
if(!current->songs) if(!current->songs)
db_playlist_count++; db_playlist_count++;
current->songs++; current->songs++;
DPRINTF(ERR_DEBUG,"Playlist now has %d entries\n",current->songs);
pnew->next = current->nodes; pnew->next = current->nodes;
current->nodes = pnew; current->nodes = pnew;
@ -588,7 +627,7 @@ int db_add(MP3FILE *pmp3) {
ppacked->time_played=0; ppacked->time_played=0;
if(gdbm_store(db_songs,dkey,*pnew,GDBM_REPLACE)) { if(gdbm_store(db_songs,dkey,*pnew,GDBM_REPLACE)) {
log_err(0,"Error inserting file %s in database\n",pmp3->fname); log_err(1,"Error inserting file %s in database\n",pmp3->fname);
} }
DPRINTF(ERR_DEBUG,"Testing for %d\n",pmp3->id); DPRINTF(ERR_DEBUG,"Testing for %d\n",pmp3->id);
@ -597,7 +636,7 @@ int db_add(MP3FILE *pmp3) {
dkey.dsize=sizeof(unsigned int); dkey.dsize=sizeof(unsigned int);
if(!gdbm_exists(db_songs,dkey)) { if(!gdbm_exists(db_songs,dkey)) {
log_err(0,"Error.. could not find just added file\n"); log_err(1,"Error.. could not find just added file\n");
} }
free(pnew->dptr); free(pnew->dptr);
@ -642,7 +681,7 @@ MP3RECORD *db_enum_begin(void) {
int err; int err;
if((err=pthread_rwlock_rdlock(&db_rwlock))) { if((err=pthread_rwlock_rdlock(&db_rwlock))) {
log_err(0,"Cannot lock rwlock\n"); log_err(1,"Cannot lock rwlock\n");
errno=err; errno=err;
return NULL; return NULL;
} }
@ -666,7 +705,7 @@ DB_PLAYLIST *db_playlist_enum_begin(void) {
DB_PLAYLIST *current; DB_PLAYLIST *current;
if((err=pthread_rwlock_rdlock(&db_rwlock))) { if((err=pthread_rwlock_rdlock(&db_rwlock))) {
log_err(0,"Cannot lock rwlock\n"); log_err(1,"Cannot lock rwlock\n");
errno=err; errno=err;
return NULL; return NULL;
} }
@ -689,7 +728,7 @@ DB_PLAYLISTENTRY *db_playlist_items_enum_begin(int playlistid) {
int err; int err;
if((err=pthread_rwlock_rdlock(&db_rwlock))) { if((err=pthread_rwlock_rdlock(&db_rwlock))) {
log_err(0,"Cannot lock rwlock\n"); log_err(1,"Cannot lock rwlock\n");
errno=err; errno=err;
return NULL; return NULL;
} }
@ -879,7 +918,7 @@ int db_get_playlist_is_smart(int playlistid) {
int result; int result;
if((err=pthread_rwlock_rdlock(&db_rwlock))) { if((err=pthread_rwlock_rdlock(&db_rwlock))) {
log_err(0,"Cannot lock rwlock\n"); log_err(1,"Cannot lock rwlock\n");
errno=err; errno=err;
return -1; return -1;
} }
@ -891,7 +930,7 @@ int db_get_playlist_is_smart(int playlistid) {
if(!current) { if(!current) {
result=0; result=0;
} else { } else {
result=1; result=current->is_smart;
} }
pthread_rwlock_unlock(&db_rwlock); pthread_rwlock_unlock(&db_rwlock);
@ -909,7 +948,7 @@ int db_get_playlist_entry_count(int playlistid) {
int err; int err;
if((err=pthread_rwlock_rdlock(&db_rwlock))) { if((err=pthread_rwlock_rdlock(&db_rwlock))) {
log_err(0,"Cannot lock rwlock\n"); log_err(1,"Cannot lock rwlock\n");
errno=err; errno=err;
return -1; return -1;
} }
@ -941,7 +980,7 @@ char *db_get_playlist_name(int playlistid) {
int err; int err;
if((err=pthread_rwlock_rdlock(&db_rwlock))) { if((err=pthread_rwlock_rdlock(&db_rwlock))) {
log_err(0,"Cannot lock rwlock\n"); log_err(1,"Cannot lock rwlock\n");
errno=err; errno=err;
return NULL; return NULL;
} }
@ -967,10 +1006,30 @@ char *db_get_playlist_name(int playlistid) {
* Check if a particular ID exists or not * Check if a particular ID exists or not
*/ */
int db_exists(int id) { int db_exists(int id) {
/* this is wrong and expensive */ int *node;
int err;
MP3FILE *pmp3; MP3FILE *pmp3;
if((err=pthread_rwlock_rdlock(&db_rwlock))) {
log_err(1,"Cannot lock rwlock\n");
errno=err;
return -1;
}
/* this is wrong and expensive */
pmp3=db_find(id); pmp3=db_find(id);
if(db_update_mode) {
/* knock it off the maybe list */
(void*)node = rbdelete((void*)&id,db_removed);
if(node) {
DPRINTF(ERR_DEBUG,"Knocked node %d from the list\n",*node);
free(node);
}
}
pthread_rwlock_unlock(&db_rwlock);
return pmp3 ? 1 : 0; return pmp3 ? 1 : 0;
} }
@ -981,12 +1040,80 @@ int db_exists(int id) {
* See when the file was last updated in the database * See when the file was last updated in the database
*/ */
int db_last_modified(int id) { int db_last_modified(int id) {
int retval;
MP3FILE *pmp3; MP3FILE *pmp3;
int err;
if((err=pthread_rwlock_rdlock(&db_rwlock))) {
log_err(1,"Cannot lock rwlock\n");
errno=err;
return -1;
}
pmp3=db_find(id); pmp3=db_find(id);
if(!pmp3) if(!pmp3) {
return 0; retval=0;
} else {
retval=pmp3->time_modified;
}
return pmp3->time_modified; pthread_rwlock_unlock(&db_rwlock);
return retval;
}
/*
* db_delete
*
* Delete an item from the database, and also remove it
* from any playlists.
*/
int db_delete(int id) {
int err;
int retval;
datum key;
DB_PLAYLIST *pcurrent;
DB_PLAYLISTENTRY *phead, *ptail;
DPRINTF(ERR_DEBUG,"Removing item %d\n",id);
if((err=pthread_rwlock_rdlock(&db_rwlock))) {
log_err(1,"Cannot lock rwlock\n");
errno=err;
return -1;
}
if(db_exists(id)) {
key.dptr=(void*)&id;
key.dsize=sizeof(int);
gdbm_delete(db_songs,key);
db_song_count--;
if(!db_update_mode)
db_version_no++;
/* walk the playlists and remove the item */
pcurrent=db_playlists.next;
while(pcurrent) {
phead=ptail=pcurrent->nodes;
while(phead && (phead->id != id)) {
ptail=phead;
phead=phead->next;
}
if(phead) { /* found it */
DPRINTF(ERR_DEBUG,"Removing from playlist %d\n",
pcurrent->id);
if(phead == pcurrent->nodes) {
pcurrent->nodes=phead->next;
} else {
ptail->next=phead->next;
}
free(phead);
}
pcurrent=pcurrent->next;
}
}
pthread_rwlock_unlock(&db_rwlock);
return 0;
} }

View File

@ -33,6 +33,7 @@ extern int db_init(char *parameters);
extern int db_deinit(void); extern int db_deinit(void);
extern int db_version(void); extern int db_version(void);
extern int db_add(MP3FILE *mp3file); extern int db_add(MP3FILE *mp3file);
extern int db_delete(int id);
extern int db_add_playlist(unsigned int playlistid, char *name, int is_smart); extern int db_add_playlist(unsigned int playlistid, char *name, int is_smart);
extern int db_add_playlist_song(unsigned int playlistid, unsigned int itemid); extern int db_add_playlist_song(unsigned int playlistid, unsigned int itemid);