diff --git a/src/db.c b/src/db.c index 3743a360..9fd0fe60 100644 --- a/src/db.c +++ b/src/db.c @@ -4353,7 +4353,7 @@ db_admin_setint64(const char *key, int64_t value) } static int -admin_get(const char *key, short type, void *value) +admin_get(void *value, const char *key, short type) { #define Q_TMPL "SELECT value FROM admin a WHERE a.key = '%q';" char *query; @@ -4364,13 +4364,7 @@ admin_get(const char *key, short type, void *value) char **strval; int ret; - query = sqlite3_mprintf(Q_TMPL, key); - if (!query) - { - DPRINTF(E_LOG, L_DB, "Out of memory for query string\n"); - - return -1; - } + CHECK_NULL(L_DB, query = sqlite3_mprintf(Q_TMPL, key)); DPRINTF(E_DBG, L_DB, "Running query '%s'\n", query); @@ -4437,52 +4431,22 @@ admin_get(const char *key, short type, void *value) #undef Q_TMPL } -char * -db_admin_get(const char *key) +int +db_admin_get(char **value, const char *key) { - char *value = NULL; - int ret; - - ret = admin_get(key, DB_TYPE_STRING, &value); - if (ret < 0) - { - DPRINTF(E_DBG, L_DB, "Could not find key '%s' in admin table\n", key); - return NULL; - } - - return value; + return admin_get(value, key, DB_TYPE_STRING); } int -db_admin_getint(const char *key) +db_admin_getint(int *intval, const char *key) { - int value = 0; - int ret; - - ret = admin_get(key, DB_TYPE_INT, &value); - if (ret < 0) - { - DPRINTF(E_DBG, L_DB, "Could not find key '%s' in admin table\n", key); - return 0; - } - - return value; + return admin_get(intval, key, DB_TYPE_INT); } -int64_t -db_admin_getint64(const char *key) +int +db_admin_getint64(int64_t *int64val, const char *key) { - int64_t value = 0; - int ret; - - ret = admin_get(key, DB_TYPE_INT64, &value); - if (ret < 0) - { - DPRINTF(E_DBG, L_DB, "Could not find key '%s' in admin table\n", key); - return 0; - } - - return value; + return admin_get(int64val, key, DB_TYPE_INT64); } int @@ -4586,11 +4550,11 @@ db_speaker_clear_all(void) static int queue_transaction_begin() { - int queue_version; + int queue_version = 0; db_transaction_begin(); - queue_version = db_admin_getint(DB_ADMIN_QUEUE_VERSION); + db_admin_getint(&queue_version, DB_ADMIN_QUEUE_VERSION); queue_version++; return queue_version; @@ -6938,22 +6902,22 @@ db_check_version(void) { #define Q_VACUUM "VACUUM;" char *errmsg; - int db_ver_major; - int db_ver_minor; + int db_ver_major = 0; + int db_ver_minor = 0; int db_ver; int vacuum; int ret; vacuum = cfg_getbool(cfg_getsec(cfg, "sqlite"), "vacuum"); - db_ver_major = db_admin_getint(DB_ADMIN_SCHEMA_VERSION_MAJOR); + db_admin_getint(&db_ver_major, DB_ADMIN_SCHEMA_VERSION_MAJOR); if (!db_ver_major) - db_ver_major = db_admin_getint(DB_ADMIN_SCHEMA_VERSION); // Pre schema v15.1 + db_admin_getint(&db_ver_major, DB_ADMIN_SCHEMA_VERSION); // Pre schema v15.1 if (!db_ver_major) return 1; // Will create new database - db_ver_minor = db_admin_getint(DB_ADMIN_SCHEMA_VERSION_MINOR); + db_admin_getint(&db_ver_minor, DB_ADMIN_SCHEMA_VERSION_MINOR); db_ver = db_ver_major * 100 + db_ver_minor; diff --git a/src/db.h b/src/db.h index e1c52604..c900057e 100644 --- a/src/db.h +++ b/src/db.h @@ -771,14 +771,14 @@ db_admin_setint(const char *key, int value); int db_admin_setint64(const char *key, int64_t value); -char * -db_admin_get(const char *key); +int +db_admin_get(char **value, const char *key); int -db_admin_getint(const char *key); +db_admin_getint(int *intval, const char *key); -int64_t -db_admin_getint64(const char *key); +int +db_admin_getint64(int64_t *int64val, const char *key); int db_admin_delete(const char *key); diff --git a/src/httpd.c b/src/httpd.c index 4a3ce341..817bfe52 100644 --- a/src/httpd.c +++ b/src/httpd.c @@ -319,7 +319,7 @@ httpd_request_etag_matches(struct evhttp_request *req, const char *etag) * @return True if the given timestamp matches the request-header-value "If-Modified-Since", otherwise false */ bool -httpd_request_not_modified_since(struct evhttp_request *req, const time_t *mtime) +httpd_request_not_modified_since(struct evhttp_request *req, time_t mtime) { struct evkeyvalq *input_headers; struct evkeyvalq *output_headers; @@ -329,7 +329,7 @@ httpd_request_not_modified_since(struct evhttp_request *req, const time_t *mtime input_headers = evhttp_request_get_input_headers(req); modified_since = evhttp_find_header(input_headers, "If-Modified-Since"); - strftime(last_modified, sizeof(last_modified), "%a, %d %b %Y %H:%M:%S %Z", gmtime(mtime)); + strftime(last_modified, sizeof(last_modified), "%a, %d %b %Y %H:%M:%S %Z", gmtime(&mtime)); // Return not modified, if given timestamp matches "If-Modified-Since" request header if (modified_since && (strcasecmp(last_modified, modified_since) == 0)) @@ -455,7 +455,7 @@ serve_file(struct evhttp_request *req, const char *uri) return; } - if (httpd_request_not_modified_since(req, &sb.st_mtime)) + if (httpd_request_not_modified_since(req, sb.st_mtime)) { httpd_send_reply(req, HTTP_NOTMODIFIED, NULL, NULL, HTTPD_SEND_NO_GZIP); return; diff --git a/src/httpd.h b/src/httpd.h index 16253027..de295442 100644 --- a/src/httpd.h +++ b/src/httpd.h @@ -102,7 +102,7 @@ void httpd_stream_file(struct evhttp_request *req, int id); bool -httpd_request_not_modified_since(struct evhttp_request *req, const time_t *mtime); +httpd_request_not_modified_since(struct evhttp_request *req, time_t mtime); bool httpd_request_etag_matches(struct evhttp_request *req, const char *etag); diff --git a/src/httpd_jsonapi.c b/src/httpd_jsonapi.c index 4a263a51..0787d777 100644 --- a/src/httpd_jsonapi.c +++ b/src/httpd_jsonapi.c @@ -67,6 +67,16 @@ static char *default_playlist_directory; /* -------------------------------- HELPERS --------------------------------- */ +static bool +is_modified(struct evhttp_request *req, const char *key) +{ + int64_t db_update = 0; + + db_admin_getint64(&db_update, key); + + return (!db_update || !httpd_request_not_modified_since(req, (time_t)db_update)); +} + static inline void safe_json_add_string(json_object *obj, const char *key, const char *value) { @@ -1023,10 +1033,19 @@ jsonapi_reply_library(struct httpd_request *hreq) DPRINTF(E_LOG, L_WEB, "library: failed to get file count info\n"); } - safe_json_add_time_from_string(jreply, "started_at", (s = db_admin_get(DB_ADMIN_START_TIME)), true); - free(s); - safe_json_add_time_from_string(jreply, "updated_at", (s = db_admin_get(DB_ADMIN_DB_UPDATE)), true); - free(s); + ret = db_admin_get(&s, DB_ADMIN_START_TIME); + if (ret == 0) + { + safe_json_add_time_from_string(jreply, "started_at", s, true); + free(s); + } + + ret = db_admin_get(&s, DB_ADMIN_DB_UPDATE); + if (ret == 0) + { + safe_json_add_time_from_string(jreply, "updated_at", s, true); + free(s); + } json_object_object_add(jreply, "updating", json_object_new_boolean(library_is_scanning())); @@ -2458,7 +2477,7 @@ jsonapi_reply_queue(struct httpd_request *hreq) uint32_t item_id; uint32_t count; int start_pos, end_pos; - int version; + int version = 0; char etag[21]; struct player_status status; struct db_queue_item queue_item; @@ -2467,7 +2486,7 @@ jsonapi_reply_queue(struct httpd_request *hreq) json_object *item; int ret = 0; - version = db_admin_getint(DB_ADMIN_QUEUE_VERSION); + db_admin_getint(&version, DB_ADMIN_QUEUE_VERSION); db_queue_get_count(&count); snprintf(etag, sizeof(etag), "%d", version); @@ -2715,7 +2734,6 @@ jsonapi_reply_player_volume(struct httpd_request *hreq) static int jsonapi_reply_library_artists(struct httpd_request *hreq) { - time_t db_update; struct query_params query_params; const char *param; enum media_kind media_kind; @@ -2724,11 +2742,9 @@ jsonapi_reply_library_artists(struct httpd_request *hreq) int total; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_UPDATE); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE)) return HTTP_NOTMODIFIED; - media_kind = 0; param = evhttp_find_header(hreq->query, "media_kind"); if (param) @@ -2782,16 +2798,13 @@ jsonapi_reply_library_artists(struct httpd_request *hreq) static int jsonapi_reply_library_artist(struct httpd_request *hreq) { - time_t db_update; const char *artist_id; json_object *reply; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_UPDATE); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE)) return HTTP_NOTMODIFIED; - artist_id = hreq->uri_parsed->path_parts[3]; reply = fetch_artist(artist_id); @@ -2817,7 +2830,6 @@ jsonapi_reply_library_artist(struct httpd_request *hreq) static int jsonapi_reply_library_artist_albums(struct httpd_request *hreq) { - time_t db_update; struct query_params query_params; const char *artist_id; json_object *reply; @@ -2825,11 +2837,9 @@ jsonapi_reply_library_artist_albums(struct httpd_request *hreq) int total; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_UPDATE); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE)) return HTTP_NOTMODIFIED; - artist_id = hreq->uri_parsed->path_parts[3]; reply = json_object_new_object(); @@ -2872,7 +2882,6 @@ jsonapi_reply_library_artist_albums(struct httpd_request *hreq) static int jsonapi_reply_library_albums(struct httpd_request *hreq) { - time_t db_update; struct query_params query_params; const char *param; enum media_kind media_kind; @@ -2881,11 +2890,9 @@ jsonapi_reply_library_albums(struct httpd_request *hreq) int total; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_UPDATE); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE)) return HTTP_NOTMODIFIED; - media_kind = 0; param = evhttp_find_header(hreq->query, "media_kind"); if (param) @@ -2939,16 +2946,13 @@ jsonapi_reply_library_albums(struct httpd_request *hreq) static int jsonapi_reply_library_album(struct httpd_request *hreq) { - time_t db_update; const char *album_id; json_object *reply; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_UPDATE); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE)) return HTTP_NOTMODIFIED; - album_id = hreq->uri_parsed->path_parts[3]; reply = fetch_album(album_id); @@ -2974,7 +2978,6 @@ jsonapi_reply_library_album(struct httpd_request *hreq) static int jsonapi_reply_library_album_tracks(struct httpd_request *hreq) { - time_t db_update; struct query_params query_params; const char *album_id; json_object *reply; @@ -2982,11 +2985,9 @@ jsonapi_reply_library_album_tracks(struct httpd_request *hreq) int total; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_MODIFIED); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_MODIFIED)) return HTTP_NOTMODIFIED; - album_id = hreq->uri_parsed->path_parts[3]; reply = json_object_new_object(); @@ -3029,18 +3030,15 @@ jsonapi_reply_library_album_tracks(struct httpd_request *hreq) static int jsonapi_reply_library_tracks_get_byid(struct httpd_request *hreq) { - time_t db_update; struct query_params query_params; const char *track_id; struct db_media_file_info dbmfi; json_object *reply = NULL; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_MODIFIED); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_MODIFIED)) return HTTP_NOTMODIFIED; - track_id = hreq->uri_parsed->path_parts[3]; memset(&query_params, 0, sizeof(struct query_params)); @@ -3133,18 +3131,15 @@ jsonapi_reply_library_tracks_put_byid(struct httpd_request *hreq) static int jsonapi_reply_library_playlists(struct httpd_request *hreq) { - time_t db_update; struct query_params query_params; json_object *reply; json_object *items; int total; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_UPDATE); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE)) return HTTP_NOTMODIFIED; - reply = json_object_new_object(); items = json_object_new_array(); json_object_object_add(reply, "items", items); @@ -3185,16 +3180,13 @@ jsonapi_reply_library_playlists(struct httpd_request *hreq) static int jsonapi_reply_library_playlist(struct httpd_request *hreq) { - time_t db_update; const char *playlist_id; json_object *reply; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_UPDATE); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE)) return HTTP_NOTMODIFIED; - playlist_id = hreq->uri_parsed->path_parts[3]; reply = fetch_playlist(playlist_id); @@ -3220,7 +3212,6 @@ jsonapi_reply_library_playlist(struct httpd_request *hreq) static int jsonapi_reply_library_playlist_tracks(struct httpd_request *hreq) { - time_t db_update; struct query_params query_params; json_object *reply; json_object *items; @@ -3228,11 +3219,9 @@ jsonapi_reply_library_playlist_tracks(struct httpd_request *hreq) int total; int ret = 0; - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_MODIFIED); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_MODIFIED)) return HTTP_NOTMODIFIED; - ret = safe_atoi32(hreq->uri_parsed->path_parts[3], &playlist_id); if (ret < 0) { @@ -3325,7 +3314,6 @@ jsonapi_reply_queue_save(struct httpd_request *hreq) static int jsonapi_reply_library_genres(struct httpd_request *hreq) { - time_t db_update; struct query_params query_params; const char *param; enum media_kind media_kind; @@ -3334,9 +3322,7 @@ jsonapi_reply_library_genres(struct httpd_request *hreq) int total; int ret; - - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_UPDATE); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE)) return HTTP_NOTMODIFIED; media_kind = 0; @@ -3394,7 +3380,6 @@ jsonapi_reply_library_genres(struct httpd_request *hreq) static int jsonapi_reply_library_count(struct httpd_request *hreq) { - time_t db_update; const char *param_expression; char *expression; struct smartpl smartpl_expression; @@ -3403,9 +3388,7 @@ jsonapi_reply_library_count(struct httpd_request *hreq) json_object *jreply; int ret; - - db_update = (time_t) db_admin_getint64(DB_ADMIN_DB_UPDATE); - if (db_update && httpd_request_not_modified_since(hreq->req, &db_update)) + if (!is_modified(hreq->req, DB_ADMIN_DB_UPDATE)) return HTTP_NOTMODIFIED; memset(&qp, 0, sizeof(struct query_params)); diff --git a/src/lastfm.c b/src/lastfm.c index 6e18620b..52895ede 100644 --- a/src/lastfm.c +++ b/src/lastfm.c @@ -422,8 +422,10 @@ lastfm_is_enabled(void) int lastfm_init(void) { - lastfm_session_key = db_admin_get(DB_ADMIN_LASTFM_SESSION_KEY); - if (!lastfm_session_key) + int ret; + + ret = db_admin_get(&lastfm_session_key, DB_ADMIN_LASTFM_SESSION_KEY); + if (ret < 0) { DPRINTF(E_DBG, L_LASTFM, "No valid LastFM session key\n"); lastfm_disabled = true; diff --git a/src/mpd.c b/src/mpd.c index cfbf5aad..5a411d62 100644 --- a/src/mpd.c +++ b/src/mpd.c @@ -959,7 +959,7 @@ mpd_command_status(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, { struct player_status status; uint32_t queue_length = 0; - int queue_version; + int queue_version = 0; char *state; uint32_t itemid = 0; struct db_queue_item *queue_item; @@ -981,7 +981,7 @@ mpd_command_status(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, break; } - queue_version = db_admin_getint(DB_ADMIN_QUEUE_VERSION); + db_admin_getint(&queue_version, DB_ADMIN_QUEUE_VERSION); db_queue_get_count(&queue_length); evbuffer_add_printf(evbuf, @@ -1062,9 +1062,9 @@ mpd_command_stats(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, { struct query_params qp; struct filecount_info fci; - time_t start_time; double uptime; - int64_t db_update; + int64_t db_start = 0; + int64_t db_update = 0; int ret; memset(&qp, 0, sizeof(struct query_params)); @@ -1077,9 +1077,9 @@ mpd_command_stats(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, return ACK_ERROR_UNKNOWN; } - start_time = (time_t) db_admin_getint64(DB_ADMIN_START_TIME); - uptime = difftime(time(NULL), start_time); - db_update = db_admin_getint64(DB_ADMIN_DB_UPDATE); + db_admin_getint64(&db_start, DB_ADMIN_START_TIME); + uptime = difftime(time(NULL), (time_t) db_start); + db_admin_getint64(&db_update, DB_ADMIN_DB_UPDATE); //TODO [mpd] Implement missing stats attributes (playtime) evbuffer_add_printf(evbuf, diff --git a/src/settings.c b/src/settings.c index 699b8431..a3989dcb 100644 --- a/src/settings.c +++ b/src/settings.c @@ -109,28 +109,40 @@ settings_option_get(struct settings_category *category, const char *name) int settings_option_getint(struct settings_option *option) { + int intval = 0; + if (!option || option->type != SETTINGS_TYPE_INT) return 0; - return db_admin_getint(option->name); + db_admin_getint(&intval, option->name); + + return intval; } bool settings_option_getbool(struct settings_option *option) { + int intval = 0; + if (!option || option->type != SETTINGS_TYPE_BOOL) return false; - return db_admin_getint(option->name) > 0; + db_admin_getint(&intval, option->name); + + return (intval != 0); } char * settings_option_getstr(struct settings_option *option) { + char *s = NULL; + if (!option || option->type != SETTINGS_TYPE_STR) return NULL; - return db_admin_get(option->name); + db_admin_get(&s, option->name); + + return s; } int diff --git a/src/spotify_webapi.c b/src/spotify_webapi.c index 338f9293..5cc76875 100644 --- a/src/spotify_webapi.c +++ b/src/spotify_webapi.c @@ -419,8 +419,8 @@ token_refresh(void) return 0; } - refresh_token = db_admin_get(DB_ADMIN_SPOTIFY_REFRESH_TOKEN); - if (!refresh_token) + ret = db_admin_get(&refresh_token, DB_ADMIN_SPOTIFY_REFRESH_TOKEN); + if (ret < 0) { DPRINTF(E_LOG, L_SPOTIFY, "No spotify refresh token found\n"); goto error;