add browse
This commit is contained in:
parent
0df3ad01e1
commit
352f627471
|
@ -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,14 +577,19 @@ 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))) {
|
||||||
|
total_size += record_size;
|
||||||
*count = *count + 1;
|
*count = *count + 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(err != SQLITE_DONE) {
|
if(err != SQLITE_DONE) {
|
||||||
sqlite_finalize(db_sqlite_pvm,&perr);
|
sqlite_finalize(db_sqlite_pvm,&perr);
|
||||||
|
@ -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,15 +614,16 @@ 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);
|
||||||
|
if(result_size) {
|
||||||
presult=(unsigned char*)malloc(result_size);
|
presult=(unsigned char*)malloc(result_size);
|
||||||
if(!presult)
|
if(!presult)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -619,7 +631,10 @@ int db_sqlite_enum_fetch(DBQUERYINFO *pinfo, unsigned char **pdmap) {
|
||||||
DPRINTF(E_DBG,L_DB,"Building response for %s (size %d)\n",valarray[3],result_size);
|
DPRINTF(E_DBG,L_DB,"Building response for %s (size %d)\n",valarray[3],result_size);
|
||||||
*pdmap = presult;
|
*pdmap = presult;
|
||||||
return result_size;
|
return result_size;
|
||||||
} else if(err == SQLITE_DONE) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in New Issue