diff options
author | Ulf Lilleengen <lulf@carrot.studby.ntnu.no> | 2008-08-05 21:50:54 +0200 |
---|---|---|
committer | Ulf Lilleengen <lulf@carrot.studby.ntnu.no> | 2008-08-05 21:50:54 +0200 |
commit | 56e69975c0998e3d134865062f90d71fde8208d8 (patch) | |
tree | cba19d193b9154123c60ec2bf50a2cd304cd2820 | |
parent | d96674123da3fb8e3d7b517c719512c69c249ba8 (diff) |
- Abstract out the methods listing artists and genre into their own functions.
- Use a format string in mp3_list to determine what type of arguments to be
bound to the sqlite3 statement. This got a bit uglier than expected, so it may
be removed later. But it's the best we've got for now.
This revision have not been tested to work.
-rw-r--r-- | include/mp3fs.h | 4 | ||||
-rw-r--r-- | src/mp3_subr.c | 93 | ||||
-rwxr-xr-x | src/mp3_vnops.c | 85 |
3 files changed, 97 insertions, 85 deletions
diff --git a/include/mp3fs.h b/include/mp3fs.h index 816af61..4be9c44 100644 --- a/include/mp3fs.h +++ b/include/mp3fs.h @@ -24,7 +24,9 @@ struct filler_data { fuse_fill_dir_t filler; }; -void mp3_list(int, struct filler_data *, char *); +void mp3_list(int, struct filler_data *, const char *, const char *, ...); +void mp3_list_artist(char *, struct filler_data *); +void mp3_list_genre(char *, struct filler_data *); char *mp3_gettoken(const char *, int); int mp3_numtoken(const char *); #endif diff --git a/src/mp3_subr.c b/src/mp3_subr.c index c765ca9..05b9162 100644 --- a/src/mp3_subr.c +++ b/src/mp3_subr.c @@ -225,15 +225,19 @@ mp3_scan(char *filepath) /* * Perform query and list the result from field. + * XXX: The varargs stuff got a bit uglier than I anticipated. I think i'd like + * to remove it perhaps... */ void -mp3_list(int field, struct filler_data *fd, char *query) +mp3_list(int field, struct filler_data *fd, const char *query, const char *fmt, ...) { sqlite3_stmt *st; fuse_fill_dir_t filler; void *buf; const unsigned char *value; - int error, ret; + char *s; + va_list ap; + int d, error, ret; filler = fd->filler; buf = fd->buf; @@ -249,6 +253,21 @@ mp3_list(int field, struct filler_data *fd, char *query) // warnx("Error preparing statement\n"); return; } + va_start(ap, fmt); + int count = 1; + while (*fmt) { + switch (*fmt++) { + case 's': + s = va_arg(ap, char *); + sqlite3_bind_text(st, count++, s, -1, SQLITE_STATIC); + break; + case 'd': + d = va_arg(ap, int); + sqlite3_bind_int(st, count++, d); + break; + } + } + va_end(ap); ret = sqlite3_step(st); while (ret == SQLITE_ROW) { value = sqlite3_column_text(st, field); @@ -329,3 +348,73 @@ mp3_gettoken(const char *str, int toknum) ret[size] = '\0'; return (ret); } + +void +mp3_list_artist(const char *path, struct filler_data *fd) +{ + char *name, *album; + + switch (mp3_numtoken(path)) { + case 1: + mp3_list(0, fd, "SELECT name FROM artist", ""); + break; + case 2: + /* So, now we got to find out the artist and list its albums. */ + name = mp3_gettoken(path, 2); + if (name == NULL) + break; + mp3_list(0, fd, "SELECT DISTINCT album FROM song, artist " + "WHERE song.artistname = artist.name AND artist.name LIKE " + "'?'", "%s", name); + free(name); + break; + case 3: + /* List songs in an album. */ + name = mp3_gettoken(path, 2); + if (name == NULL) + break; + album = mp3_gettoken(path, 3); + if (album == NULL) + break; + mp3_list(0, fd, "SELECT title FROM song, artist WHERE " + "song.artistname = artist.name AND ARTIST.name LIKE '?' " + "AND song.album LIKE '?'", "%s%s", name, album); + free(album); + free(name); + break; + } +} + +void +mp3_list_genre(const char *path, struct filler_data *fd) +{ + char *genre, *album; + + switch (mp3_numtoken(path)) { + case 1: + mp3_list(0, fd, "SELECT name FROM genre", ""); + break; + case 2: + genre = mp3_gettoken(path, 2); + if (genre == NULL) + break; + mp3_list(0, fd, "SELECT DISTINCT album FROM song, genre WHERE" + " song.genrename = genre.name AND genre.name LIKE '?'", + "%s", genre); + free(genre); + break; + case 3: + genre = mp3_gettoken(path, 2); + if (genre == NULL) + break; + album = mp3_gettoken(path, 3); + if (album == NULL) + break; + mp3_list(0, fd, "SELECT title FROM song, genre WHERE " + "song.genrename = genre.name AND genre.name LIKE '?' " + " AND song.album LIKE '?'", "%s%s", genre, album); + free(album); + free(genre); + break; + } +} diff --git a/src/mp3_vnops.c b/src/mp3_vnops.c index 9d592ae..dec7ecb 100755 --- a/src/mp3_vnops.c +++ b/src/mp3_vnops.c @@ -60,7 +60,6 @@ static int mp3_readdir (const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { struct filler_data fd; - char *album, *genre, *name, *query; filler (buf, ".", NULL, 0); filler (buf, "..", NULL, 0); @@ -80,91 +79,13 @@ static int mp3_readdir (const char *path, void *buf, fuse_fill_dir_t filler, * 3. Return the list of those mp3s. */ if (strncmp(path, "/Artists", 8) == 0) { - switch (mp3_numtoken(path)) { - // XXX: Put these into generic functions that can be - // reused. - case 1: - mp3_list(0, &fd, "SELECT name FROM artist"); - break; - case 2: - /* So, now we got to find out the artist and list its albums. */ - name = mp3_gettoken(path, 2); - if (name == NULL) - break; - asprintf(&query, "SELECT DISTINCT album FROM " - "song, artist WHERE song.artistname = " - "artist.name AND artist.name LIKE '%s'", - name); - if (query == NULL) - break; - mp3_list(0, &fd, query); - free(query); - free(name); - break; - case 3: - /* List songs in an album. */ - name = mp3_gettoken(path, 2); - if (name == NULL) - break; - album = mp3_gettoken(path, 3); - if (album == NULL) - break; - asprintf(&query, "SELECT title FROM song, " - "artist WHERE song.artistname = artist.name" - " AND ARTIST.name LIKE '%s' AND song.album " - " LIKE '%s'", name, album); - if (query == NULL) - break; - mp3_list(0, &fd, query); - free(query); - free(album); - free(name); - break; - } + mp3_list_artist(path, &fd); return (0); } else if (strncmp(path, "/Genres", 7) == 0) { - switch (mp3_numtoken(path)) { - // XXX: Put these into generic functions that can be - // reused. - case 1: - mp3_list(0, &fd, "SELECT name FROM genre"); - break; - case 2: - genre = mp3_gettoken(path, 2); - if (genre == NULL) - break; - asprintf(&query, "SELECT DISTINCT album FROM " - "song, genre WHERE song.genrename = " - "genre.name AND genre.name LIKE '%s'", - genre); - if (query == NULL) - break; - mp3_list(0, &fd, query); - free(query); - free(genre); - break; - case 3: - genre = mp3_gettoken(path, 2); - if (genre == NULL) - break; - album = mp3_gettoken(path, 3); - if (album == NULL) - break; - asprintf(&query, "SELECT title FROM song, genre " - "WHERE song.genrename = genre.name AND " - "genre.name LIKE '%s' AND song.album LIKE " - "'%s'", genre, album); - if (query == NULL) - break; - mp3_list(0, &fd, query); - free(query); - free(album); - free(genre); - break; - } + mp3_list_genre(path, &fd); return (0); } else if (strcmp(path, "/Tracks") == 0) { - mp3_list(0, &fd, "SELECT title FROM song"); + mp3_list(0, &fd, "SELECT title FROM song", ""); return (0); } |