core/database: Introduce the dbe_read() database operation

This function allocates and returns a new database entry using
information read from a file.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-09-22 09:24:19 -04:00
parent c77ca65630
commit 2da33f1c75
21 changed files with 98 additions and 136 deletions

View File

@ -34,20 +34,23 @@ void index_entry :: write(file &file)
set_write(&file, &ie_set);
}
void index_entry :: read(file &file)
static struct db_entry *index_read(struct file *file)
{
gchar *key = file_readl(&file);
struct index_entry *ent = new index_entry;
gchar *key = file_readl(file);
ie_key = key;
ent->ie_key = key;
g_free(key);
set_read(&file, &ie_set);
set_read(file, &ent->ie_set);
return ent;
}
static const struct db_ops index_ops = {
index_alloc,
index_free,
index_read,
NULL,
};

View File

@ -18,8 +18,9 @@ static const std::string __album_key(const std::string &name, unsigned int year)
return res;
}
static void __album_from_key(struct album *album, const gchar *key)
static struct album *__album_from_key(const gchar *key)
{
struct album *album = new struct album;
gchar *name, *lower;
if (sscanf(key, "%u %m[^\n]", &album->al_year, &name) == 1)
@ -31,6 +32,7 @@ static void __album_from_key(struct album *album, const gchar *key)
g_free(name);
g_free(lower);
return album;
}
@ -38,9 +40,7 @@ album :: album() : al_year(0), al_name("") {}
static struct db_entry *album_alloc(const gchar *key)
{
struct album *album = new struct album;
__album_from_key(album, key);
return album;
return __album_from_key(key);
}
static void album_free(struct db_entry *dbe)
@ -53,11 +53,12 @@ const std::string album :: primary_key() const
return __album_key(al_name, al_year);
}
void album :: read(file &file)
static struct db_entry *album_read(struct file *file)
{
gchar *line = file_readl(&file);
__album_from_key(this, line);
gchar *line = file_readl(file);
struct album *album = __album_from_key(line);
g_free(line);
return album;
}
void album :: write(file &file)
@ -69,6 +70,7 @@ void album :: write(file &file)
static const struct db_ops album_ops = {
album_alloc,
album_free,
album_read,
NULL,
};

View File

@ -34,16 +34,12 @@ const std::string artist :: primary_key() const
return ar_name;
}
void artist :: read(file &file)
struct db_entry *artist_read(struct file *file)
{
gchar *name = file_readl(&file);
gchar *g_lc = string_lowercase(name);
ar_name = name;
ar_lower = g_lc;
gchar *name = file_readl(file);
struct artist *artist = (struct artist *)artist_alloc(name);
g_free(name);
g_free(g_lc);
return artist;
}
void artist :: write(file &file)
@ -55,6 +51,7 @@ void artist :: write(file &file)
static const struct db_ops artist_ops = {
artist_alloc,
artist_free,
artist_read,
NULL,
};

View File

@ -33,16 +33,12 @@ const std::string genre :: primary_key() const
return ge_name;
}
void genre :: read(file &file)
static struct db_entry *genre_read(struct file *file)
{
gchar *name = file_readl(&file);
gchar *g_lc = string_lowercase(name);
ge_name = name;
ge_lower = g_lc;
gchar *name = file_readl(file);
struct genre *genre = (struct genre *)genre_alloc(name);
g_free(name);
g_free(g_lc);
return genre;
}
void genre :: write(file &file)
@ -54,6 +50,7 @@ void genre :: write(file &file)
static const struct db_ops genre_ops = {
genre_alloc,
genre_free,
genre_read,
NULL,
};

View File

@ -31,17 +31,20 @@ const std::string library :: primary_key() const
return li_path;
}
void library :: read(file &file)
static struct db_entry *library_read(struct file *file)
{
int enabled;
struct library *library = new struct library;
gchar *path;
int enabled;
file_readf(&file, "%d\n", &enabled);
li_enabled = enabled;
file_readf(file, "%d\n", &enabled);
library->li_enabled = enabled;
path = file_readl(file);
library->li_path = path;
path = file_readl(&file);
li_path = path;
g_free(path);
return library;
}
void library :: write(file &file)
@ -53,6 +56,7 @@ void library :: write(file &file)
static const struct db_ops library_ops = {
library_alloc,
library_free,
library_read,
NULL,
};

View File

@ -100,30 +100,32 @@ const std::string track :: primary_key() const
return __track_key(tr_library, tr_path);
}
void track :: read(file &file)
static struct db_entry *track_read(struct file *file)
{
unsigned int library_id, artist_id, album_id, genre_id;
struct track *track = new struct track;
gchar *path, *name, *lower;
file_readf(&file, "%u %u %u %u %u", &library_id, &artist_id,
&album_id, &genre_id, &tr_track);
date_read(&file, &tr_date);
file_readf(&file, "%u %u", &tr_count, &tr_length);
file_readf(file, "%u %u %u %u %u", &library_id, &artist_id, &album_id,
&genre_id, &track->tr_track);
date_read(file, &track->tr_date);
file_readf(file, "%u %u", &track->tr_count, &track->tr_length);
name = file_readl(&file);
path = file_readl(&file);
name = file_readl(file);
path = file_readl(file);
lower = string_lowercase(name);
tr_title = name;
tr_path = path;
tr_lower = lower;
track->tr_title = name;
track->tr_path = path;
track->tr_lower = lower;
g_free(name);
g_free(path);
g_free(lower);
tr_library = library_get(library_id);
tr_artist = artist_get(artist_id);
tr_album = album_get(album_id);
tr_genre = genre_get(genre_id);
track->tr_library = library_get(library_id);
track->tr_artist = artist_get(artist_id);
track->tr_album = album_get(album_id);
track->tr_genre = genre_get(genre_id);
return track;
}
void track :: write(file &file)
@ -140,6 +142,7 @@ void track :: write(file &file)
static const struct db_ops track_ops = {
NULL,
track_free,
track_read,
track_setup,
};

View File

@ -39,14 +39,6 @@ struct db_entry {
* @param file File to use when writing data.
*/
virtual void write(file &) = 0;
/**
* This function is called by the Database to read a single
* DatabaseEntry instance from disk.
*
* @param file File to use when reading data.
*/
virtual void read(file &) = 0;
};
@ -57,6 +49,9 @@ struct db_ops {
/* Free a struct db_entry. */
void (*dbe_free)(struct db_entry *);
/* Read a single struct db_entry from disk. */
struct db_entry *(*dbe_read)(struct file *);
/* Set up a struct db_entry after adding to the database. */
void (*dbe_setup)(struct db_entry *);
};

View File

@ -7,7 +7,6 @@
#ifndef OCARINA_DATABASE_HPP
#define OCARINA_DATABASE_HPP
template <class T>
static inline void __dbe_free(struct database<T> *db, struct db_entry *dbe)
{
@ -19,6 +18,20 @@ static inline void __dbe_free(struct database<T> *db, struct db_entry *dbe)
}
}
template <class T>
static inline struct db_entry *__dbe_read(struct database<T> *db, unsigned int index)
{
struct db_entry *dbe = NULL;
int valid;
file_readf(&db->db_file, "%d", &valid);
if (valid)
dbe = db->db_ops->dbe_read(&db->db_file);
db->db_entries[index] = (T *)dbe;
return dbe;
}
template <class T>
static inline void __dbe_setup(struct database<T> *db, unsigned int index)
{
@ -82,7 +95,6 @@ template <class T>
void db_load(struct database<T> *db)
{
unsigned int size;
int valid;
if (file_open(&db->db_file, OPEN_READ) == false)
return;
@ -90,14 +102,8 @@ void db_load(struct database<T> *db)
file_readf(&db->db_file, "%u", &size);
db->db_entries.resize(size);
for (unsigned int i = 0; i < size; i++) {
file_readf(&db->db_file, "%d", &valid);
if (valid == false) {
db->db_entries[i] = NULL;
} else {
db->db_entries[i] = new T;
db->db_entries[i]->read(db->db_file);
if (__dbe_read(db, i))
__dbe_setup(db, i);
}
}
file_close(&db->db_file);

View File

@ -35,13 +35,6 @@ struct index_entry : public db_entry {
* @param file The file to use when writing data.
*/
void write(file &);
/**
* Read an IndexEntry from file.
*
* @param file The file read from.
*/
void read(file &);
};

View File

@ -33,13 +33,6 @@ struct album : public db_entry {
*/
const std::string primary_key() const;
/**
* Read album information from file.
*
* @param file The file to read from.
*/
void read(file &);
/**
* Write album information to file.
*

View File

@ -17,7 +17,6 @@ struct artist : public db_entry {
artist(); /**< Artist tag constructor. */
const std::string primary_key() const;
void read(file &);
void write(file &);
};

View File

@ -18,7 +18,6 @@ public:
genre(); /**< Genre tag constructor. */
const std::string primary_key() const;
void read(file &);
void write(file &);
};

View File

@ -31,13 +31,6 @@ struct library : public db_entry {
*/
const std::string primary_key() const;
/**
* Read library information from file.
*
* @param file The file to read from.
*/
void read(file &);
/**
* Write library information to file.
*

View File

@ -46,13 +46,6 @@ struct track : public db_entry {
const std::string primary_key() const;
/**
* Read track data from file.
*
* @param file The file to read from.
*/
void read(file &);
/**
* Write track data to file.
*

View File

@ -27,7 +27,6 @@ struct int_entry : public db_entry {
}
void write(file &f) { file_writef(&f, "%u", ie_val); }
void read(file &f) { file_readf(&f, "%u", &ie_val); }
};
static unsigned int test_free_count = 0;
@ -46,6 +45,13 @@ static void int_free(struct db_entry *dbe)
delete (struct int_entry *)dbe;
}
static struct db_entry *int_read(struct file *f)
{
struct int_entry *ent = new int_entry;
file_readf(f, "%u", &ent->ie_val);
return ent;
}
static void int_setup(struct db_entry *dbe)
{
test_setup_count++;
@ -54,6 +60,7 @@ static void int_setup(struct db_entry *dbe)
static const struct db_ops int_ops = {
int_alloc,
int_free,
int_read,
int_setup,
};
@ -76,12 +83,8 @@ static void test_db_entry()
int_ops.dbe_free(ent);
test_equal(test_free_count, 1);
ent = new int_entry();
test_equal(ent->ie_val, 0);
test_equal(ent->primary_key(), "0");
file_open(&f, OPEN_READ);
ent->read(f);
ent = (struct int_entry *)int_ops.dbe_read(&f);
file_close(&f);
int_ops.dbe_setup(ent);

View File

@ -33,16 +33,13 @@ static void test_entry()
file_close(&f);
index_ops->dbe_free(ie);
ie = new index_entry();
test_equal(ie->primary_key(), "");
test_equal(set_size(&ie->ie_set), 0);
file_open(&f, OPEN_READ);
ie->read(f);
ie = (struct index_entry *)index_ops->dbe_read(&f);
test_equal(ie->primary_key(), "Zelda");
test_equal(set_size(&ie->ie_set), 0);
index_ops->dbe_free(ie);
ie->read(f);
ie = (struct index_entry *)index_ops->dbe_read(&f);
test_equal(ie->primary_key(), "Link");
test_equal(set_size(&ie->ie_set), 3);
file_close(&f);

View File

@ -36,14 +36,12 @@ static void test_album()
file_close(&f);
album_ops->dbe_free(album);
album = new struct album();
test_verify_empty(album);
file_open(&f, OPEN_READ);
album->read(f);
album = (struct album *)album_ops->dbe_read(&f);
test_verify_empty(album);
album_ops->dbe_free(album);
album->read(f);
album = (struct album *)album_ops->dbe_read(&f);
file_close(&f);
test_verify_hyrule(album);
album_ops->dbe_free(album);

View File

@ -35,16 +35,14 @@ static void test_artist()
file_close(&f);
artist_ops->dbe_free(artist);
artist = new struct artist();
test_verify_empty(artist);
file_open(&f, OPEN_READ);
file_readf(&f, "%u", &i);
artist->read(f);
artist = (struct artist *)artist_ops->dbe_read(&f);
test_verify_empty(artist);
artist_ops->dbe_free(artist);
file_readf(&f, "%u", &i);
artist->read(f);
artist = (struct artist *)artist_ops->dbe_read(&f);
file_close(&f);
test_verify_koji(artist);
artist_ops->dbe_free(artist);

View File

@ -35,16 +35,14 @@ static void test_genre()
file_close(&f);
genre_ops->dbe_free(genre);
genre = new struct genre();
test_verify_empty(genre);
file_open(&f, OPEN_READ);
file_readf(&f, "%u", &i);
genre->read(f);
genre = (struct genre *)genre_ops->dbe_read(&f);
test_verify_empty(genre);
genre_ops->dbe_free(genre);
file_readf(&f, "%u", &i);
genre->read(f);
genre = (struct genre *)genre_ops->dbe_read(&f);
file_close(&f);
test_verify_vg(genre);
genre_ops->dbe_free(genre);

View File

@ -4,13 +4,6 @@
#include <core/tags/library.h>
#include "../test.h"
static void test_verify_empty(struct library *library)
{
test_equal(library->primary_key(), "");
test_equal(library->li_enabled, false);
test_equal(library->li_size, 0);
}
static void test_verify_zelda(struct library *library)
{
test_equal(library->primary_key(), "/home/Zelda/Music");
@ -28,7 +21,7 @@ static void test_verify_link(struct library *library)
static void test_library()
{
const struct db_ops *library_ops = test_library_ops();
struct library *link, *zelda, *library = new struct library();
struct library *link, *zelda, *library;
file f;
link = (struct library *)library_ops->dbe_alloc("/home/Link/Music");
@ -37,7 +30,6 @@ static void test_library()
library_set_enabled(link, false);
test_verify_link(link);
test_verify_zelda(zelda);
test_verify_empty(library);
link->li_size = 21;
zelda->li_size = 42;
@ -50,11 +42,12 @@ static void test_library()
file_close(&f);
file_open(&f, OPEN_READ);
library->read(f);
library = (struct library *)library_ops->dbe_read(&f);
test_verify_link(library);
test_equal(library_file(library, "navi.mp3"), "/home/Link/Music/navi.mp3");
library_ops->dbe_free(library);
library->read(f);
library = (struct library *)library_ops->dbe_read(&f);
file_close(&f);
test_verify_zelda(library);
test_equal(library_file(library, "impa.ogg"), "/home/Zelda/Music/impa.ogg");

View File

@ -107,16 +107,14 @@ static void test_track()
track_ops->dbe_free(track);
test_equal(library->li_size, 0);
track = new struct track;
file_open(&f, OPEN_READ);
track->read(f);
track = (struct track *)track_ops->dbe_read(&f);
track_ops->dbe_setup(track);
test_verify_notrack(track);
test_equal(library->li_size, 1);
track_ops->dbe_free(track);
track = new struct track;
track->read(f);
track = (struct track *)track_ops->dbe_read(&f);
track_ops->dbe_setup(track);
test_verify_track(track);
test_equal(library->li_size, 1);