ocarina/core/tags/library.c

123 lines
2.4 KiB
C

/*
* Copyright 2014 (c) Anna Schumaker.
*/
#include <core/string.h>
#include <core/tags/library.h>
#define LIBRARY_DB_MIN 0 /* Ocarina 6.0 */
static struct database library_db;
static struct library *__library_alloc(gchar *path)
{
struct library *library = g_malloc(sizeof(struct library));
dbe_init(&library->li_dbe, library);
library->li_path = path;
library->li_playlist = NULL;
return library;
}
static struct db_entry *library_alloc(const gchar *path, unsigned int index)
{
return &__library_alloc(g_strdup(path))->li_dbe;
}
static void library_free(struct db_entry *dbe)
{
g_free(LIBRARY(dbe));
}
static gchar *library_key(struct db_entry *dbe)
{
return LIBRARY(dbe)->li_path;
}
static struct db_entry *library_read(struct file *file, unsigned int index)
{
gchar *path;
/* Old "enabled" flag */
if (file_version(file) == 0)
file_readd(file);
path = file_readl(file);
return &__library_alloc(path)->li_dbe;
}
static void library_write(struct file *file, struct db_entry *dbe)
{
file_writef(file, "%s", LIBRARY(dbe)->li_path);
}
static const struct db_ops library_ops = {
.dbe_alloc = library_alloc,
.dbe_free = library_free,
.dbe_key = library_key,
.dbe_read = library_read,
.dbe_write = library_write,
};
void library_db_init()
{
db_init(&library_db, "library.db", true, &library_ops, LIBRARY_DB_MIN);
db_load(&library_db);
}
void library_db_deinit()
{
db_deinit(&library_db);
}
bool library_db_defrag()
{
return db_defrag(&library_db);
}
const struct database *library_db_get()
{
return &library_db;
}
struct library *library_find(const gchar *path)
{
struct library *library = library_lookup(path);
if (library)
return library;
return LIBRARY(db_insert(&library_db, path));
}
struct library *library_lookup(const gchar *path)
{
struct db_entry *dbe, *next;
db_for_each(dbe, next, &library_db) {
if (string_is_subdir(path, LIBRARY(dbe)->li_path))
return LIBRARY(dbe);
}
return NULL;
}
struct library *library_get(const unsigned int index)
{
return LIBRARY(db_at(&library_db, index));
}
void library_remove(struct library *library)
{
if (library)
db_remove(&library_db, &library->li_dbe);
}
gchar *library_file(struct library *library, const gchar *path)
{
return g_strdup_printf("%s/%s", library->li_path, path);
}
#ifdef CONFIG_TESTING
const struct db_ops *test_library_ops() { return &library_ops; }
#endif /* CONFIG_TESTING */