summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Lilleengen <lulf@carrot.studby.ntnu.no>2008-08-05 21:50:54 +0200
committerUlf Lilleengen <lulf@carrot.studby.ntnu.no>2008-08-05 21:50:54 +0200
commit56e69975c0998e3d134865062f90d71fde8208d8 (patch)
treecba19d193b9154123c60ec2bf50a2cd304cd2820
parentd96674123da3fb8e3d7b517c719512c69c249ba8 (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.h4
-rw-r--r--src/mp3_subr.c93
-rwxr-xr-xsrc/mp3_vnops.c85
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);
}