/*
* This file is part of DisOrder
- * Copyright (C) 2005, 2006 Richard Kettlewell
+ * Copyright (C) 2005, 2006, 2007 Richard Kettlewell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
struct vector v;
char **w;
int nw;
+ const char *rootless = track_rootless(track);
+ if(!rootless)
+ rootless = track; /* bodge */
vector_init(&v);
- if((w = words(casefold(strip_extension(track_rootless(track))), &nw)))
+ if((w = words(casefold(strip_extension(rootless)), &nw)))
vector_append_many(&v, w, nw);
for(; p; p = p->next)
const char *s = config->alias, *t, *expansion, *part;
int c, used_db = 0, slash_prefix, err;
struct kvp *at;
+ const char *const root = find_track_root(track);
- if(strstr(track, "Troggs"))
- D(("computing alias for %s", track));
+ if(!root) {
+ /* Bodge for tracks with no root */
+ *aliasp = 0;
+ return 0;
+ }
dynstr_init(&d);
- dynstr_append_string(&d, find_track_root(track));
+ dynstr_append_string(&d, root);
while((c = (unsigned char)*s++)) {
if(c != '{') {
dynstr_append(&d, c);
* an alias) */
switch(err = trackdb_getdata(trackdb_tracksdb, d.vec, &at, tid)) {
case 0:
- if(strstr(track, "Troggs"))
- D(("found a hit for alias"));
if((s = kvp_get(at, "_alias_for"))
&& !strcmp(s, track)) {
case DB_NOTFOUND:
- if(strstr(track, "Troggs"))
- D(("accepting anyway"));
*aliasp = d.vec;
} else {
- if(strstr(track, "Troggs")) {
- D(("rejecting"));
- D(("%s", track));
- D(("%s", s ? s : "(null)"));
- }
*aliasp = 0;
}
return 0;
int err, cmp;
char *oldalias, *newalias, **oldtags = 0, **newtags;
+ if(value) {
+ /* TODO: if value matches default then set value=0 */
+ }
+
for(;;) {
tid = trackdb_begin_transaction();
if((err = gettrackdata(track, &t, &p, 0,
}
/* Check whether a track is suitable for random play. Returns 0 if it is,
- * DB_NOTFOUND if it or DB_LOCK_DEADLOCK. */
+ * DB_NOTFOUND if it is not or DB_LOCK_DEADLOCK if the database gave us
+ * that. */
static int check_suitable(const char *track,
DB_TXN *tid,
char **required_tags,
struct kvp *p, *t;
const char *pick_at_random, *played_time;
+ /* don't pick tracks that aren't in any surviving collection (for instance
+ * you've edited the config but the rescan hasn't done its job yet) */
+ if(!find_track_root(track)) {
+ info("found track not in any collection: %s", track);
+ return DB_NOTFOUND;
+ }
/* don't pick aliases - only pick the canonical form */
if(gettrackdata(track, &t, &p, 0, 0, tid) == DB_LOCK_DEADLOCK)
return DB_LOCK_DEADLOCK;
} else {
/* No required tags. We pick random record numbers in the database
* instead. */
- switch(err = trackdb_tracksdb->stat(trackdb_tracksdb, tid, &sp,
- DB_RECORDCOUNT)) {
+ switch(err = trackdb_tracksdb->stat(trackdb_tracksdb, tid, &sp, 0)) {
case 0:
break;
case DB_LOCK_DEADLOCK:
DB_TXN *tid) {
DBC *cursor;
DBT k, d;
- size_t root_len = strlen(root);
- int err;
+ const size_t root_len = root ? strlen(root) : 0;
+ int err, cberr;
struct kvp *data;
+ const char *track;
cursor = trackdb_opencursor(trackdb_tracksdb, tid);
- err = cursor->c_get(cursor, make_key(&k, root), prepare_data(&d),
- DB_SET_RANGE);
+ if(root)
+ err = cursor->c_get(cursor, make_key(&k, root), prepare_data(&d),
+ DB_SET_RANGE);
+ else {
+ memset(&k, 0, sizeof k);
+ err = cursor->c_get(cursor, &k, prepare_data(&d),
+ DB_FIRST);
+ }
while(!err) {
- if(k.size > root_len
- && !strncmp(k.data, root, root_len)
- && ((char *)k.data)[root_len] == '/') {
+ if(!root
+ || (k.size > root_len
+ && !strncmp(k.data, root, root_len)
+ && ((char *)k.data)[root_len] == '/')) {
data = kvp_urldecode(d.data, d.size);
- if(kvp_get(data, "_path"))
- if((err = callback(xstrndup(k.data, k.size), data, u, tid)))
+ if(kvp_get(data, "_path")) {
+ track = xstrndup(k.data, k.size);
+ /* Advance to the next track before the callback so that the callback
+ * may safely delete the track */
+ err = cursor->c_get(cursor, &k, &d, DB_NEXT);
+ if((cberr = callback(track, data, u, tid))) {
+ err = cberr;
break;
- err = cursor->c_get(cursor, &k, &d, DB_NEXT);
+ }
+ } else
+ err = cursor->c_get(cursor, &k, &d, DB_NEXT);
} else
break;
}
indent-tabs-mode:nil
End:
*/
-/* arch-tag:/CBQ6uebrasgkefvjc+fHQ */