Permalink
Browse files

Transfer playcount, restartposition and lastplay to kvstore.db

This used to reside in meta.db but I'd rather like to keep this
in the kvstore. Much simples and it will be a lot easier to split
out this for storing into xattr in filesystems instead

Note: This issues a non-backwards-compatible db changes so any
previous versions of showtime will not be able to read the metadata
database after this upgrade
  • Loading branch information...
andoma committed Feb 12, 2014
1 parent 36e70f5 commit 2f8d497ca97468e23386a7c71c0a0dcd3c44fabc
View
@@ -1282,7 +1282,7 @@ be_sidplayer_play(const char *url0, media_pipe_t *mp,
if(!registered_play && mb->mb_pts > PLAYINFO_AUDIO_PLAY_THRESHOLD) {
registered_play = 1;
- playinfo_register_play(url0, 1, CONTENT_AUDIO);
+ playinfo_register_play(url0, 1);
}
sample += CHUNK_SIZE;
View
@@ -0,0 +1,39 @@
+-- schema-upgrade:disable-fk
+
+CREATE TABLE playcount_tmp(url, val);
+INSERT INTO playcount_tmp SELECT url, playcount FROM item WHERE playcount > 0;
+INSERT OR IGNORE INTO kvstore.url(url) SELECT url FROM playcount_tmp;
+INSERT INTO kvstore.url_kv SELECT id, 1, "playcount", val FROM playcount_tmp, kvstore.url WHERE playcount_tmp.url = url.url;
+DROP TABLE playcount_tmp;
+
+CREATE TABLE restartposition_tmp(url, val);
+INSERT INTO restartposition_tmp SELECT url, restartposition FROM item WHERE restartposition > 0;
+INSERT OR IGNORE INTO kvstore.url(url) SELECT url FROM restartposition_tmp;
+INSERT INTO kvstore.url_kv SELECT id, 1, "restartposition", val FROM restartposition_tmp, kvstore.url WHERE restartposition_tmp.url = url.url;
+DROP TABLE restartposition_tmp;
+
+CREATE TABLE lastplay_tmp(url, val);
+INSERT INTO lastplay_tmp SELECT url, lastplay FROM item WHERE lastplay > 0;
+INSERT OR IGNORE INTO kvstore.url(url) SELECT url FROM lastplay_tmp;
+INSERT INTO kvstore.url_kv SELECT id, 1, "lastplay", val FROM lastplay_tmp, kvstore.url WHERE lastplay_tmp.url = url.url;
+DROP TABLE lastplay_tmp;
+
+
+CREATE TABLE item_tmp (
+ id INTEGER PRIMARY KEY,
+ url TEXT NOT NULL UNIQUE,
+ contenttype INTEGER,
+ mtime INTEGER,
+ parent INTEGER,
+ ds_id INTEGER REFERENCES datasource(id) ON DELETE SET NULL,
+ usertitle TEXT,
+ indexstatus DEFAULT 0);
+
+
+INSERT INTO item_tmp SELECT id,url,contenttype,mtime,parent,ds_id,usertitle,indexstatus FROM item;
+
+DROP TABLE item;
+
+ALTER TABLE item_tmp RENAME TO item;
+
+CREATE INDEX item_url_idx ON item(url);
View
@@ -1293,7 +1293,7 @@ hls_play(hls_t *h, media_pipe_t *mp, char *errbuf, size_t errlen,
if(spp >= video_settings.played_threshold || event_is_type(e, EVENT_EOF)) {
playinfo_set_restartpos(canonical_url, -1);
- playinfo_register_play(canonical_url, 1, CONTENT_VIDEO);
+ playinfo_register_play(canonical_url, 1);
TRACE(TRACE_DEBUG, "Video",
"Playback reached %d%%, counting as played (%s)",
spp, canonical_url);
View
@@ -732,7 +732,7 @@ rtmp_playvideo(const char *url0, media_pipe_t *mp,
mp_become_primary(mp);
- playinfo_register_play(va.canonical_url, 0, CONTENT_VIDEO);
+ playinfo_register_play(va.canonical_url, 0);
r.canonical_url = va.canonical_url;
r.restartpos_last = -1;
@@ -749,7 +749,7 @@ rtmp_playvideo(const char *url0, media_pipe_t *mp,
if(p >= video_settings.played_threshold) {
TRACE(TRACE_DEBUG, "RTMP", "Playback reached %d%%, counting as played",
p);
- playinfo_register_play(va.canonical_url, 1, CONTENT_VIDEO);
+ playinfo_register_play(va.canonical_url, 1);
playinfo_set_restartpos(va.canonical_url, -1);
}
}
View
@@ -210,16 +210,32 @@ db_rollback_deadlock0(sqlite3 *db, const char *src)
*
*/
int
-db_upgrade_schema(sqlite3 *db, const char *schemadir, const char *dbname)
+db_upgrade_schema(sqlite3 *db, const char *schemadir, const char *dbname,
+ const char *extra_db, const char *extra_db_path)
{
int ver, tgtver = 0;
char path[256];
char buf[256];
+ char detach[256];
+
+ if(extra_db != NULL) {
+ char tmp[256];
+ snprintf(tmp, sizeof(tmp),
+ "ATTACH DATABASE '%s' AS %s", extra_db_path, extra_db);
+ snprintf(detach, sizeof(detach), "DETACH DATABASE %s", extra_db);
+ if(db_one_statement(db, tmp, NULL)) {
+ TRACE(TRACE_ERROR, "DB", "%s: Unable to %s", tmp);
+ return -1;
+ }
+ } else {
+ detach[0] = 0;
+ }
db_one_statement(db, "pragma journal_mode=wal;", NULL);
if(db_get_int_from_query(db, "pragma user_version", &ver)) {
TRACE(TRACE_ERROR, "DB", "%s: Unable to query db version", dbname);
+ if(detach[0]) db_one_statement(db, detach, NULL);
return -1;
}
@@ -231,6 +247,7 @@ db_upgrade_schema(sqlite3 *db, const char *schemadir, const char *dbname)
if(fd == NULL) {
TRACE(TRACE_ERROR, "DB",
"%s: Unable to scan schema dir %s -- %s", dbname, schemadir , buf);
+ if(detach[0]) db_one_statement(db, detach, NULL);
return -1;
}
@@ -245,13 +262,17 @@ db_upgrade_schema(sqlite3 *db, const char *schemadir, const char *dbname)
if(ver > tgtver) {
TRACE(TRACE_ERROR, "DB", "%s: Installed version %d is too high for "
"this version of Showtime", dbname, ver);
+ if(detach[0]) db_one_statement(db, detach, NULL);
return -1;
}
+ int enable_fk = 0;
+
while(1) {
if(ver == tgtver) {
TRACE(TRACE_DEBUG, "DB", "%s: At current version %d", dbname, ver);
+ if(detach[0]) db_one_statement(db, detach, NULL);
return 0;
}
@@ -265,9 +286,16 @@ db_upgrade_schema(sqlite3 *db, const char *schemadir, const char *dbname)
TRACE(TRACE_ERROR, "DB",
"%s: Unable to upgrade db schema to version %d using %s -- %s",
dbname, ver, path, buf);
+ if(detach[0]) db_one_statement(db, detach, NULL);
return -1;
}
+
+ if(strstr(buf_cstr(sql), "-- schema-upgrade:disable-fk")) {
+ db_one_statement(db, "PRAGMA foreign_keys=OFF;", NULL);
+ enable_fk = 1;
+ }
+
db_begin(db);
snprintf(buf, sizeof(buf), "PRAGMA user_version=%d", ver);
if(db_one_statement(db, buf, NULL)) {
@@ -298,11 +326,19 @@ db_upgrade_schema(sqlite3 *db, const char *schemadir, const char *dbname)
}
db_commit(db);
+ if(enable_fk) {
+ db_one_statement(db, "PRAGMA foreign_keys=ON;", NULL);
+ enable_fk = 0;
+ }
TRACE(TRACE_INFO, "DB", "%s: Upgraded to version %d", dbname, ver);
buf_release(sql);
}
fail:
+ if(detach[0]) db_one_statement(db, detach, NULL);
db_rollback(db);
+
+ if(enable_fk)
+ db_one_statement(db, "PRAGMA foreign_keys=ON;", NULL);
return -1;
}
View
@@ -56,7 +56,8 @@ int db_preparex(sqlite3 *db, sqlite3_stmt **ppStmt, const char *zSql,
sqlite3 *db_open(const char *path, int flags);
-int db_upgrade_schema(sqlite3 *db, const char *schemadir, const char *dbname);
+int db_upgrade_schema(sqlite3 *db, const char *schemadir, const char *dbname,
+ const char *extra_db, const char *extra_db_path);
typedef struct db_pool db_pool_t;
View
@@ -50,6 +50,7 @@ typedef struct kvstore_deferred_write {
union {
char *kdw_string;
int kdw_int;
+ int64_t kdw_int64;
};
} kvstore_deferred_write_t;
@@ -116,7 +117,7 @@ kvstore_init(void)
snprintf(buf, sizeof(buf), "%s/resources/kvstore", showtime_dataroot());
- int r = db_upgrade_schema(db, buf, "kvstore");
+ int r = db_upgrade_schema(db, buf, "kvstore", NULL, NULL);
kvstore_close(db);
@@ -511,6 +512,22 @@ kv_url_opt_get_int(const char *url, int domain, const char *key, int def)
}
+/**
+ *
+ */
+int64_t
+kv_url_opt_get_int64(const char *url, int domain, const char *key, int64_t def)
+{
+ void *db = kvstore_get();
+ sqlite3_stmt *stmt = kv_url_opt_get(db, url, domain, key);
+ int64_t v = def;
+ if(stmt) {
+ v = sqlite3_column_int64(stmt, 0);
+ sqlite3_finalize(stmt);
+ }
+ kvstore_close(db);
+ return v;
+}
/**
@@ -575,6 +592,10 @@ kv_url_opt_set(const char *url, int domain, const char *key,
sqlite3_bind_int(stmt, 3, va_arg(apx, int));
break;
+ case KVSTORE_SET_INT64:
+ sqlite3_bind_int64(stmt, 3, va_arg(apx, int64_t));
+ break;
+
case KVSTORE_SET_STRING:
str = va_arg(apx, const char *);
if(str != NULL) {
@@ -663,6 +684,10 @@ kvstore_deferred_flush(void)
sqlite3_bind_int(stmt, 3, kdw->kdw_int);
break;
+ case KVSTORE_SET_INT64:
+ sqlite3_bind_int(stmt, 3, kdw->kdw_int64);
+ break;
+
case KVSTORE_SET_STRING:
sqlite3_bind_text(stmt, 3, kdw->kdw_string, -1, SQLITE_STATIC);
break;
@@ -754,6 +779,10 @@ kv_url_opt_set_deferred(const char *url, int domain, const char *key,
kdw->kdw_int = va_arg(ap, int);
break;
+ case KVSTORE_SET_INT64:
+ kdw->kdw_int64 = va_arg(ap, int64_t);
+ break;
+
case KVSTORE_SET_STRING:
str = va_arg(ap, const char *);
if(str != NULL) {
View
@@ -42,9 +42,13 @@ rstr_t *kv_url_opt_get_rstr(const char *url, int domain, const char *key);
int kv_url_opt_get_int(const char *url, int domain, const char *key, int def);
+int64_t kv_url_opt_get_int64(const char *url, int domain,
+ const char *key, int64_t def);
+
#define KVSTORE_SET_STRING 1
#define KVSTORE_SET_INT 2
#define KVSTORE_SET_VOID 3
+#define KVSTORE_SET_INT64 4
void kv_url_opt_set(const char *url, int domain, const char *key,
int type, ...);
@@ -323,7 +323,7 @@ be_file_playaudio(const char *url, media_pipe_t *mp,
if(registered_play == 0) {
if(ets->ts > PLAYINFO_AUDIO_PLAY_THRESHOLD) {
registered_play = 1;
- playinfo_register_play(url, 1, CONTENT_AUDIO);
+ playinfo_register_play(url, 1);
}
}
@@ -351,8 +351,7 @@ deep_probe(fa_dir_entry_t *fde, scanner_t *s)
if(fde->fde_prop != NULL && !fde->fde_bound_to_metadb) {
fde->fde_bound_to_metadb = 1;
- playinfo_bind_url_to_prop(getdb(s), rstr_get(fde->fde_url),
- fde->fde_prop);
+ playinfo_bind_url_to_prop(rstr_get(fde->fde_url), fde->fde_prop);
}
}
@@ -432,7 +432,7 @@ video_player_loop(AVFormatContext *fctx, media_codec_t **cwvec,
if(spp >= video_settings.played_threshold || event_is_type(e, EVENT_EOF)) {
playinfo_set_restartpos(canonical_url, -1);
- playinfo_register_play(canonical_url, 1, CONTENT_VIDEO);
+ playinfo_register_play(canonical_url, 1);
TRACE(TRACE_DEBUG, "Video",
"Playback reached %d%%, counting as played (%s)",
spp, canonical_url);
@@ -861,7 +861,7 @@ be_file_playvideo_fh(const char *url, media_pipe_t *mp,
seek_index_t *si = build_index(mp, fctx, url);
seek_index_t *ci = build_chapters(mp, fctx, url);
- playinfo_register_play(va.canonical_url, 0, CONTENT_VIDEO);
+ playinfo_register_play(va.canonical_url, 0);
event_t *e;
e = video_player_loop(fctx, cwvec, mp, va.flags, errbuf, errlen,
View
@@ -145,7 +145,7 @@ js_db_upgrade(JSContext *cx, JSObject *obj, uintN argc,
if(!JS_ConvertArguments(cx, argc, argv, "s", &path))
return JS_FALSE;
- r = db_upgrade_schema(jd->jd_db, path, jd->jd_name);
+ r = db_upgrade_schema(jd->jd_db, path, jd->jd_name, NULL, NULL);
*rval = BOOLEAN_TO_JSVAL(!r);
return JS_TRUE;
View
@@ -35,6 +35,7 @@
#include "prop/prop_nodefilter.h"
#include "event.h"
#include "metadata/playinfo.h"
+#include "metadata/metadata.h"
#include "htsmsg/htsmsg_json.h"
TAILQ_HEAD(js_item_queue, js_item);
@@ -668,7 +669,7 @@ js_appendItem0(JSContext *cx, js_model_t *model, prop_t *parent,
*rval = JSVAL_VOID;
if(metabind != NULL)
- playinfo_bind_url_to_prop(NULL, metabind, item);
+ playinfo_bind_url_to_prop(metabind, item);
if(type != NULL) {
prop_set_string(prop_create(item, "type"), type);
@@ -1056,7 +1056,7 @@ mark_content_as(deco_browse_t *db, int content_type, int seen)
LIST_FOREACH(di, &db->db_items_per_ct[content_type], di_type_link)
urls[i++] = rstr_get(di->di_url);
- playinfo_mark_urls_as(urls, num_videos, seen, content_type);
+ playinfo_mark_urls_as(urls, num_videos, seen);
free(urls);
}
View
@@ -106,6 +106,7 @@ metadb_init(void)
{
sqlite3 *db;
char buf[256];
+ char buf2[256];
snprintf(buf, sizeof(buf), "%s/metadb", gconf.persistent_path);
mkdir(buf, 0770);
@@ -119,8 +120,9 @@ metadb_init(void)
return;
snprintf(buf, sizeof(buf), "%s/resources/metadb", showtime_dataroot());
+ snprintf(buf2, sizeof(buf2), "%s/kvstore/kvstore.db", gconf.persistent_path);
- int r = db_upgrade_schema(db, buf, "metadb");
+ int r = db_upgrade_schema(db, buf, "metadb", "kvstore", buf2);
metadb_close(db);
Oops, something went wrong.

0 comments on commit 2f8d497

Please sign in to comment.