I have a sort of database with a many-to-many association between tags and files. For various reasons, I decided to forgo a junction table in favor of having the left and right tables store the associated values in the tables themselves. However I've ended up writing code like this:
GHashTable *tagdb_get_tag_files (tagdb *db, int tag_code)
{
return g_hash_table_lookup(db->reverse, GINT_TO_POINTER(tag_code));
}
GHashTable *tagdb_get_file_tags (tagdb *db, int file_id)
{
return g_hash_table_lookup(db->forward, GINT_TO_POINTER(file_id));
}
void tagdb_remove_tag (tagdb *db, int id)
{
GHashTable *its_files = g_hash_table_lookup(db->reverse, GINT_TO_POINTER(id));
if (its_files == NULL)
{
return;
}
GHashTableIter it;
gpointer key, value;
g_hash_table_iter_init(&it, its_files);
if (g_hash_table_iter_next(&it, &key, &value))
{
tagdb_remove_tag_from_file(db, id, key);
}
g_hash_table_remove(db->reverse, GINT_TO_POINTER(id));
}
void tagdb_remove_file(tagdb *db, int id)
{
GHashTable *its_tags = g_hash_table_lookup(db->forward, GINT_TO_POINTER(id));
if (its_tags == NULL)
{
return;
}
GHashTableIter it;
gpointer key, value;
g_hash_table_iter_init(&it, its_tags);
if (g_hash_table_iter_next(&it, &key, &value))
{
tagdb_remove_file_from_tag(db, id, key);
}
g_hash_table_remove(db->forward, GINT_TO_POINTER(id));
}
Where only a few identifiers change, but basically the same thing happens, just on different sides. Is there a simpler, less error prone way to do this in c? Maybe with macros?
db->forwardanddb->reverse– Loki Astari Mar 4 '12 at 3:23HashTable*– 2ck Mar 4 '12 at 3:49