core/database: Introduce the dbe_setup() database operation
Track tags need to add themselves to the filter index and update the library track count once added to the database. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
parent
c8021639ba
commit
c77ca65630
|
@ -48,6 +48,7 @@ void index_entry :: read(file &file)
|
||||||
static const struct db_ops index_ops = {
|
static const struct db_ops index_ops = {
|
||||||
index_alloc,
|
index_alloc,
|
||||||
index_free,
|
index_free,
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ void album :: write(file &file)
|
||||||
static const struct db_ops album_ops = {
|
static const struct db_ops album_ops = {
|
||||||
album_alloc,
|
album_alloc,
|
||||||
album_free,
|
album_free,
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ void artist :: write(file &file)
|
||||||
static const struct db_ops artist_ops = {
|
static const struct db_ops artist_ops = {
|
||||||
artist_alloc,
|
artist_alloc,
|
||||||
artist_free,
|
artist_free,
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ void genre :: write(file &file)
|
||||||
static const struct db_ops genre_ops = {
|
static const struct db_ops genre_ops = {
|
||||||
genre_alloc,
|
genre_alloc,
|
||||||
genre_free,
|
genre_free,
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ void library :: write(file &file)
|
||||||
static const struct db_ops library_ops = {
|
static const struct db_ops library_ops = {
|
||||||
library_alloc,
|
library_alloc,
|
||||||
library_free,
|
library_free,
|
||||||
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,23 +58,17 @@ track :: track(const std::string &key)
|
||||||
tr_artist = artist_find(taglib_tag_artist(tag));
|
tr_artist = artist_find(taglib_tag_artist(tag));
|
||||||
tr_genre = genre_find(taglib_tag_genre(tag));
|
tr_genre = genre_find(taglib_tag_genre(tag));
|
||||||
tr_library = library;
|
tr_library = library;
|
||||||
tr_library->li_size++;
|
|
||||||
|
|
||||||
date_set(&tr_date, 0, 0, 0);
|
|
||||||
tr_count = 0;
|
tr_count = 0;
|
||||||
tr_length = taglib_audioproperties_length(audio);
|
tr_length = taglib_audioproperties_length(audio);
|
||||||
tr_track = taglib_tag_track(tag);
|
tr_track = taglib_tag_track(tag);
|
||||||
|
date_set(&tr_date, 0, 0, 0);
|
||||||
|
|
||||||
tr_path = path;
|
tr_path = path;
|
||||||
tr_title = taglib_tag_title(tag);
|
tr_title = taglib_tag_title(tag);
|
||||||
lower = string_lowercase(tr_title.c_str());
|
lower = string_lowercase(tr_title.c_str());
|
||||||
tr_lower = lower;
|
tr_lower = lower;
|
||||||
|
|
||||||
date_set(&tr_date, 0, 0, 0);
|
|
||||||
filter :: add(tr_title, dbe_index);
|
|
||||||
filter :: add(tr_artist->ar_name, dbe_index);
|
|
||||||
filter :: add(tr_album->al_name, dbe_index);
|
|
||||||
|
|
||||||
taglib_tag_free_strings();
|
taglib_tag_free_strings();
|
||||||
taglib_file_free(file);
|
taglib_file_free(file);
|
||||||
g_free(lower);
|
g_free(lower);
|
||||||
|
@ -91,6 +85,16 @@ static void track_free(struct db_entry *dbe)
|
||||||
delete track;
|
delete track;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void track_setup(struct db_entry *dbe)
|
||||||
|
{
|
||||||
|
struct track *track = (struct track *)dbe;
|
||||||
|
|
||||||
|
filter :: add(track->tr_title, track->dbe_index);
|
||||||
|
filter :: add(track->tr_artist->ar_name, track->dbe_index);
|
||||||
|
filter :: add(track->tr_album->al_name, track->dbe_index);
|
||||||
|
track->tr_library->li_size++;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string track :: primary_key() const
|
const std::string track :: primary_key() const
|
||||||
{
|
{
|
||||||
return __track_key(tr_library, tr_path);
|
return __track_key(tr_library, tr_path);
|
||||||
|
@ -120,11 +124,6 @@ void track :: read(file &file)
|
||||||
tr_artist = artist_get(artist_id);
|
tr_artist = artist_get(artist_id);
|
||||||
tr_album = album_get(album_id);
|
tr_album = album_get(album_id);
|
||||||
tr_genre = genre_get(genre_id);
|
tr_genre = genre_get(genre_id);
|
||||||
|
|
||||||
filter :: add(tr_title, dbe_index);
|
|
||||||
filter :: add(tr_artist->ar_name, dbe_index);
|
|
||||||
filter :: add(tr_album->al_name, dbe_index);
|
|
||||||
tr_library->li_size++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void track :: write(file &file)
|
void track :: write(file &file)
|
||||||
|
@ -141,6 +140,7 @@ void track :: write(file &file)
|
||||||
static const struct db_ops track_ops = {
|
static const struct db_ops track_ops = {
|
||||||
NULL,
|
NULL,
|
||||||
track_free,
|
track_free,
|
||||||
|
track_setup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,9 @@ struct db_ops {
|
||||||
|
|
||||||
/* Free a struct db_entry. */
|
/* Free a struct db_entry. */
|
||||||
void (*dbe_free)(struct db_entry *);
|
void (*dbe_free)(struct db_entry *);
|
||||||
|
|
||||||
|
/* Set up a struct db_entry after adding to the database. */
|
||||||
|
void (*dbe_setup)(struct db_entry *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,20 @@ static inline void __dbe_free(struct database<T> *db, struct db_entry *dbe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static inline void __dbe_setup(struct database<T> *db, unsigned int index)
|
||||||
|
{
|
||||||
|
struct db_entry *dbe = db->db_entries[index];
|
||||||
|
|
||||||
|
if (dbe) {
|
||||||
|
dbe->dbe_index = index;
|
||||||
|
db->db_keys[dbe->primary_key()] = index;
|
||||||
|
db->db_size++;
|
||||||
|
if (db->db_ops->dbe_setup)
|
||||||
|
db->db_ops->dbe_setup(dbe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void db_init(struct database<T> *db, const char *filepath, bool autosave,
|
void db_init(struct database<T> *db, const char *filepath, bool autosave,
|
||||||
const struct db_ops *ops)
|
const struct db_ops *ops)
|
||||||
|
@ -68,7 +82,6 @@ template <class T>
|
||||||
void db_load(struct database<T> *db)
|
void db_load(struct database<T> *db)
|
||||||
{
|
{
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
std::string str;
|
|
||||||
int valid;
|
int valid;
|
||||||
|
|
||||||
if (file_open(&db->db_file, OPEN_READ) == false)
|
if (file_open(&db->db_file, OPEN_READ) == false)
|
||||||
|
@ -82,11 +95,8 @@ void db_load(struct database<T> *db)
|
||||||
db->db_entries[i] = NULL;
|
db->db_entries[i] = NULL;
|
||||||
} else {
|
} else {
|
||||||
db->db_entries[i] = new T;
|
db->db_entries[i] = new T;
|
||||||
db->db_entries[i]->dbe_index = i;
|
|
||||||
db->db_entries[i]->read(db->db_file);
|
db->db_entries[i]->read(db->db_file);
|
||||||
str = db->db_entries[i]->primary_key();
|
__dbe_setup(db, i);
|
||||||
db->db_keys[str] = i;
|
|
||||||
db->db_size++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,16 +106,12 @@ void db_load(struct database<T> *db)
|
||||||
template <class T>
|
template <class T>
|
||||||
T *db_insert(struct database<T> *db, T *item)
|
T *db_insert(struct database<T> *db, T *item)
|
||||||
{
|
{
|
||||||
if (!item)
|
if (item) {
|
||||||
return NULL;
|
db->db_entries.push_back(item);
|
||||||
|
__dbe_setup(db, db_actual_size(db) - 1);
|
||||||
item->dbe_index = db_actual_size(db);
|
db_autosave(db);
|
||||||
db->db_entries.push_back(item);
|
}
|
||||||
|
return item;
|
||||||
db->db_keys[item->primary_key()] = item->dbe_index;
|
|
||||||
db->db_size++;
|
|
||||||
db_autosave(db);
|
|
||||||
return db->db_entries[item->dbe_index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
|
@ -30,7 +30,8 @@ struct int_entry : public db_entry {
|
||||||
void read(file &f) { file_readf(&f, "%u", &ie_val); }
|
void read(file &f) { file_readf(&f, "%u", &ie_val); }
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int test_free_count = 0;
|
static unsigned int test_free_count = 0;
|
||||||
|
static unsigned int test_setup_count = 0;
|
||||||
|
|
||||||
static struct db_entry *int_alloc(const gchar *key)
|
static struct db_entry *int_alloc(const gchar *key)
|
||||||
{
|
{
|
||||||
|
@ -45,9 +46,15 @@ static void int_free(struct db_entry *dbe)
|
||||||
delete (struct int_entry *)dbe;
|
delete (struct int_entry *)dbe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void int_setup(struct db_entry *dbe)
|
||||||
|
{
|
||||||
|
test_setup_count++;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct db_ops int_ops = {
|
static const struct db_ops int_ops = {
|
||||||
int_alloc,
|
int_alloc,
|
||||||
int_free,
|
int_free,
|
||||||
|
int_setup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,8 +84,11 @@ static void test_db_entry()
|
||||||
ent->read(f);
|
ent->read(f);
|
||||||
file_close(&f);
|
file_close(&f);
|
||||||
|
|
||||||
|
int_ops.dbe_setup(ent);
|
||||||
test_equal(ent->ie_val, 1);
|
test_equal(ent->ie_val, 1);
|
||||||
test_equal(ent->primary_key(), "1");
|
test_equal(ent->primary_key(), "1");
|
||||||
|
test_equal(test_setup_count, 1);
|
||||||
|
|
||||||
int_ops.dbe_free(ent);
|
int_ops.dbe_free(ent);
|
||||||
test_equal(test_free_count, 2);
|
test_equal(test_free_count, 2);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +118,8 @@ static void test_stress(unsigned int N)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
gchar *key;
|
gchar *key;
|
||||||
|
|
||||||
test_free_count = 0;
|
test_free_count = 0;
|
||||||
|
test_setup_count = 0;
|
||||||
db_init(&db, "stress.db", false, &int_ops);
|
db_init(&db, "stress.db", false, &int_ops);
|
||||||
|
|
||||||
/* db_insert() */
|
/* db_insert() */
|
||||||
|
@ -124,6 +135,7 @@ static void test_stress(unsigned int N)
|
||||||
test_equal(dbe, NULL);
|
test_equal(dbe, NULL);
|
||||||
test_equal(db.db_size, N);
|
test_equal(db.db_size, N);
|
||||||
test_equal(db_actual_size(&db), N);
|
test_equal(db_actual_size(&db), N);
|
||||||
|
test_equal(test_setup_count, N);
|
||||||
|
|
||||||
/* db_at() */
|
/* db_at() */
|
||||||
for (i = 0; i < N; i++) {
|
for (i = 0; i < N; i++) {
|
||||||
|
@ -231,10 +243,13 @@ static void test_save_load()
|
||||||
for (i = 0; i < N; i += 2)
|
for (i = 0; i < N; i += 2)
|
||||||
db_remove(&db1, db_at(&db1, i));
|
db_remove(&db1, db_at(&db1, i));
|
||||||
|
|
||||||
i = 1;
|
|
||||||
db_deinit(&db2);
|
db_deinit(&db2);
|
||||||
|
test_setup_count = 0;
|
||||||
db_load(&db2);
|
db_load(&db2);
|
||||||
test_equal(db2.db_size, N / 2);
|
test_equal(db2.db_size, N / 2);
|
||||||
|
test_equal(test_setup_count, N / 2);
|
||||||
|
|
||||||
|
i = 1;
|
||||||
db_for_each(dbe, next, &db2) {
|
db_for_each(dbe, next, &db2) {
|
||||||
test_loop_equal(dbe->ie_val, i, i);
|
test_loop_equal(dbe->ie_val, i, i);
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
|
@ -94,6 +94,7 @@ static void test_track()
|
||||||
library = library_find("tests/Music");
|
library = library_find("tests/Music");
|
||||||
|
|
||||||
track = new struct track("0/Hyrule Symphony/01 - Title Theme.ogg");
|
track = new struct track("0/Hyrule Symphony/01 - Title Theme.ogg");
|
||||||
|
track_ops->dbe_setup(track);
|
||||||
test_verify_track(track);
|
test_verify_track(track);
|
||||||
test_equal(library->li_size, 1);
|
test_equal(library->li_size, 1);
|
||||||
|
|
||||||
|
@ -109,12 +110,14 @@ static void test_track()
|
||||||
track = new struct track;
|
track = new struct track;
|
||||||
file_open(&f, OPEN_READ);
|
file_open(&f, OPEN_READ);
|
||||||
track->read(f);
|
track->read(f);
|
||||||
|
track_ops->dbe_setup(track);
|
||||||
test_verify_notrack(track);
|
test_verify_notrack(track);
|
||||||
test_equal(library->li_size, 1);
|
test_equal(library->li_size, 1);
|
||||||
track_ops->dbe_free(track);
|
track_ops->dbe_free(track);
|
||||||
|
|
||||||
track = new struct track;
|
track = new struct track;
|
||||||
track->read(f);
|
track->read(f);
|
||||||
|
track_ops->dbe_setup(track);
|
||||||
test_verify_track(track);
|
test_verify_track(track);
|
||||||
test_equal(library->li_size, 1);
|
test_equal(library->li_size, 1);
|
||||||
file_close(&f);
|
file_close(&f);
|
||||||
|
|
Loading…
Reference in New Issue