add browse

This commit is contained in:
Ron Pedde 2005-03-13 23:20:25 +00:00
parent 0df3ad01e1
commit 352f627471
2 changed files with 97 additions and 33 deletions

View File

@ -413,6 +413,11 @@ int db_sqlite_enum_start(DBQUERYINFO *pinfo) {
const char *ptail; const char *ptail;
query[0] = '\0';
query_select[0] = '\0';
query_count[0] = '\0';
query_rest[0] = '\0';
switch(pinfo->query_type) { switch(pinfo->query_type) {
case queryTypeItems: case queryTypeItems:
strcpy(query_select,"SELECT * FROM songs "); strcpy(query_select,"SELECT * FROM songs ");
@ -452,8 +457,8 @@ int db_sqlite_enum_start(DBQUERYINFO *pinfo) {
/* Note that sqlite doesn't support COUNT(DISTINCT x) */ /* Note that sqlite doesn't support COUNT(DISTINCT x) */
case queryTypeBrowseAlbums: case queryTypeBrowseAlbums:
strcpy(query_select,"SELECT DISTINCT albums FROM songs "); strcpy(query_select,"SELECT DISTINCT album FROM songs ");
strcpy(query_count,"SELECT COUNT(albums) FROM (SELECT DISTINCT albums FROM songs "); strcpy(query_count,"SELECT COUNT(album) FROM (SELECT DISTINCT album FROM songs ");
browse=1; browse=1;
break; break;
@ -572,13 +577,18 @@ int db_sqlite_enum_size(DBQUERYINFO *pinfo, int *count) {
char *perr; char *perr;
int cols; int cols;
int total_size=0; int total_size=0;
int record_size;
DPRINTF(E_DBG,L_DB,"Enumerating size\n");
*count=0; *count=0;
db_sqlite_lock(); db_sqlite_lock();
while((err=sqlite_step(db_sqlite_pvm,&cols,&valarray,&colarray)) == SQLITE_ROW) { while((err=sqlite_step(db_sqlite_pvm,&cols,&valarray,&colarray)) == SQLITE_ROW) {
total_size += db_sqlite_get_size(pinfo,(char**)valarray); if((record_size = db_sqlite_get_size(pinfo,(char**)valarray))) {
*count = *count + 1; total_size += record_size;
*count = *count + 1;
}
} }
if(err != SQLITE_DONE) { if(err != SQLITE_DONE) {
@ -590,6 +600,7 @@ int db_sqlite_enum_size(DBQUERYINFO *pinfo, int *count) {
db_sqlite_unlock(); db_sqlite_unlock();
db_sqlite_enum_reset(pinfo); db_sqlite_enum_reset(pinfo);
DPRINTF(E_DBG,L_DB,"Got size: %d\n",total_size);
return total_size; return total_size;
} }
@ -603,23 +614,27 @@ int db_sqlite_enum_fetch(DBQUERYINFO *pinfo, unsigned char **pdmap) {
int err; int err;
char *perr; char *perr;
int cols; int cols;
int result_size; int result_size=-1;
unsigned char *presult; unsigned char *presult;
db_sqlite_lock(); db_sqlite_lock();
err=sqlite_step(db_sqlite_pvm,&cols,&valarray,&colarray); err=sqlite_step(db_sqlite_pvm,&cols,&valarray,&colarray);
db_sqlite_unlock(); db_sqlite_unlock();
if(err == SQLITE_ROW) { while((err == SQLITE_ROW) && (result_size)) {
result_size=db_sqlite_get_size(pinfo,(char**)valarray); result_size=db_sqlite_get_size(pinfo,(char**)valarray);
presult=(unsigned char*)malloc(result_size); if(result_size) {
if(!presult) presult=(unsigned char*)malloc(result_size);
return 0; if(!presult)
db_sqlite_build_dmap(pinfo,(char**)valarray,presult,result_size); return 0;
DPRINTF(E_DBG,L_DB,"Building response for %s (size %d)\n",valarray[3],result_size); db_sqlite_build_dmap(pinfo,(char**)valarray,presult,result_size);
*pdmap = presult; DPRINTF(E_DBG,L_DB,"Building response for %s (size %d)\n",valarray[3],result_size);
return result_size; *pdmap = presult;
} else if(err == SQLITE_DONE) { return result_size;
}
}
if(err == SQLITE_DONE) {
return -1; return -1;
} }
@ -653,19 +668,15 @@ int db_sqlite_enum_end(void) {
return 0; return 0;
} }
int db_sqlite_get_size(DBQUERYINFO *pinfo, char **valarray) { int db_sqlite_get_size(DBQUERYINFO *pinfo, char **valarray) {
int size; int size;
switch(pinfo->query_type) { switch(pinfo->query_type) {
case queryTypeBrowseArtists: /* simple 'mlit' entry */ case queryTypeBrowseArtists: /* simple 'mlit' entry */
return 8 + strlen(valarray[4]);
case queryTypeBrowseAlbums: case queryTypeBrowseAlbums:
return 8 + strlen(valarray[5]);
case queryTypeBrowseGenres: case queryTypeBrowseGenres:
return 8 + strlen(valarray[6]);
case queryTypeBrowseComposers: case queryTypeBrowseComposers:
return 8 + strlen(valarray[11]); return valarray[0] ? (8 + strlen(valarray[0])) : 0;
case queryTypePlaylists: case queryTypePlaylists:
size = 8; /* mlit */ size = 8; /* mlit */
size += 12; /* miid */ size += 12; /* miid */
@ -783,13 +794,10 @@ int db_sqlite_build_dmap(DBQUERYINFO *pinfo, char **valarray, char *presult, int
switch(pinfo->query_type) { switch(pinfo->query_type) {
case queryTypeBrowseArtists: /* simple 'mlit' entry */ case queryTypeBrowseArtists: /* simple 'mlit' entry */
return db_dmap_add_string(current,"mlit",valarray[4]);
case queryTypeBrowseAlbums: case queryTypeBrowseAlbums:
return db_dmap_add_string(current,"mlit",valarray[5]);
case queryTypeBrowseGenres: case queryTypeBrowseGenres:
return db_dmap_add_string(current,"mlit",valarray[6]);
case queryTypeBrowseComposers: case queryTypeBrowseComposers:
return db_dmap_add_string(current,"mlit",valarray[11]); return db_dmap_add_string(current,"mlit",valarray[0]);
case queryTypePlaylists: case queryTypePlaylists:
/* do I want to include the mlit? */ /* do I want to include the mlit? */
current += db_dmap_add_container(current,"mlit",len - 8); current += db_dmap_add_container(current,"mlit",len - 8);

View File

@ -394,9 +394,6 @@ void dispatch_playlistitems(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
(1ll << metaParentContainerId)); (1ll << metaParentContainerId));
} }
/* should build the query string here, too */
pqi->whereclause = NULL;
pqi->query_type = queryTypePlaylistItems; pqi->query_type = queryTypePlaylistItems;
pqi->index_type=indexTypeNone; pqi->index_type=indexTypeNone;
if(db_enum_start(pqi)) { if(db_enum_start(pqi)) {
@ -438,6 +435,70 @@ void dispatch_playlistitems(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
} }
void dispatch_browse(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) { void dispatch_browse(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
char browse_response[52];
char *current=browse_response;
int item_count;
int list_length;
unsigned char *block;
char *response_type;
if(!strcmp(pqi->uri_sections[3],"artists")) {
response_type = "abar";
pqi->query_type=queryTypeBrowseArtists;
} else if(!strcmp(pqi->uri_sections[3],"genres")) {
response_type = "abgn";
pqi->query_type=queryTypeBrowseGenres;
} else if(!strcmp(pqi->uri_sections[3],"albums")) {
response_type = "abal";
pqi->query_type=queryTypeBrowseAlbums;
} else if(!strcmp(pqi->uri_sections[3],"composers")) {
response_type = "abcp";
pqi->query_type=queryTypeBrowseComposers;
} else {
DPRINTF(E_WARN,L_DAAP|L_BROW,"Invalid browse request type %s\n",pqi->uri_sections[3]);
ws_returnerror(pwsc,404,"Invalid browse type");
config_set_status(pwsc,pqi->session_id,NULL);
free(pqi);
return;
}
pqi->index_type = indexTypeNone;
if(db_enum_start(pqi)) {
DPRINTF(E_LOG,L_DAAP|L_BROW,"Could not start enum\n");
ws_returnerror(pwsc,500,"Internal server error: out of memory!\n");
return;
}
DPRINTF(E_DBG,L_DAAP|L_BROW,"Getting enum size.\n");
list_length=db_enum_size(pqi,&item_count);
DPRINTF(E_DBG,L_DAAP|L_BROW,"Item enum: got %d items, dmap size: %d\n",
item_count,list_length);
current += db_dmap_add_container(current,"abro",list_length + 44);
current += db_dmap_add_int(current,"mstt",200); /* 12 */
current += db_dmap_add_int(current,"mtco",item_count); /* 12 */
current += db_dmap_add_int(current,"mrco",item_count); /* 12 */
current += db_dmap_add_container(current,response_type,list_length); /* 8 + length */
ws_addresponseheader(pwsc,"Content-Length","%d",52+list_length);
ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n");
ws_emitheaders(pwsc);
r_write(pwsc->fd,browse_response,52);
while((list_length=db_enum_fetch(pqi,&block)) > 0) {
DPRINTF(E_DBG,L_DAAP|L_BROW,"Got block of size %d\n",list_length);
r_write(pwsc->fd,block,list_length);
free(block);
}
DPRINTF(E_DBG,L_DAAP|L_BROW,"Done enumerating\n");
db_enum_end();
config_set_status(pwsc,pqi->session_id,NULL); config_set_status(pwsc,pqi->session_id,NULL);
free(pqi); free(pqi);
return; return;
@ -457,14 +518,12 @@ void dispatch_playlists(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
pqi->meta = (MetaField_t) -1ll; pqi->meta = (MetaField_t) -1ll;
} }
/* should build the query string here, too */
pqi->whereclause = NULL;
pqi->query_type = queryTypePlaylists; pqi->query_type = queryTypePlaylists;
pqi->index_type=indexTypeNone; pqi->index_type = indexTypeNone;
if(db_enum_start(pqi)) { if(db_enum_start(pqi)) {
DPRINTF(E_LOG,L_DAAP,"Could not start enum\n"); DPRINTF(E_LOG,L_DAAP,"Could not start enum\n");
ws_returnerror(pwsc,500,"Internal server error: out of memory!"); ws_returnerror(pwsc,500,"Internal server error: out of memory!\n");
return; return;
} }
@ -513,9 +572,6 @@ void dispatch_items(WS_CONNINFO *pwsc, DBQUERYINFO *pqi) {
pqi->meta = (MetaField_t) -1ll; pqi->meta = (MetaField_t) -1ll;
} }
/* should build the query string here, too */
pqi->whereclause = NULL;
pqi->query_type = queryTypeItems; pqi->query_type = queryTypeItems;
pqi->index_type=indexTypeNone; pqi->index_type=indexTypeNone;
if(db_enum_start(pqi)) { if(db_enum_start(pqi)) {