#include #include #include #include "dbutil.h" #include "util.h" int get_meta_by_name_md(struct syrep_db_context *c, const struct syrep_name*name, const struct syrep_md *md, struct syrep_meta *meta) { int ret; struct syrep_id id; DBT key, data; assert(c && c->db_id_meta && name); memset(&id, 0, sizeof(id)); memcpy(&id.name, name, sizeof(struct syrep_name)); memcpy(&id.md, md, sizeof(struct syrep_md)); memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = &id; key.size = sizeof(struct syrep_id); if ((ret = c->db_id_meta->get(c->db_id_meta, NULL, &key, &data, 0))) { if (ret == DB_NOTFOUND) return 0; c->db_id_meta->err(c->db_id_meta, ret, "id_meta::get"); return -1; } assert(data.data); if (meta) memcpy(meta, data.data, sizeof(struct syrep_meta)); return 1; } int get_current_name_by_md(struct syrep_db_context *c, const struct syrep_md *md, struct syrep_name *name) { int ret, f; struct syrep_meta meta; DBT key, data; memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = (void*) md; key.size = sizeof(struct syrep_md); if ((ret = c->db_md_lastname->get(c->db_md_lastname, NULL, &key, &data, 0))) { if (ret == DB_NOTFOUND) return 0; c->db_md_lastname->err(c->db_md_lastname, ret, "md_lastname::get()"); return -1; } assert(data.data); if ((f = get_meta_by_name_md(c, (struct syrep_name*) data.data, md, &meta)) < 0) return -1; if (!f) { fprintf(stderr, "Database inconsistency\n"); return -1; } if (meta.last_seen != c->version) return 0; if (name) memcpy(name, data.data, sizeof(struct syrep_name)); return 1; } int get_last_md_by_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_md *md) { int ret; DBT key, data; memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = (void*) name; key.size = sizeof(struct syrep_name); if ((ret = c->db_name_lastmd->get(c->db_name_lastmd, NULL, &key, &data, 0))) { if (ret == DB_NOTFOUND) { return 0; } c->db_name_lastmd->err(c->db_name_lastmd, ret, "name_lastmd::get()"); return -1; } assert(data.data); if (md) memcpy(md, data.data, sizeof(struct syrep_md)); return 1; } int get_current_md_by_name(struct syrep_db_context *c, const struct syrep_name *name, struct syrep_md *md) { struct syrep_md lmd; struct syrep_meta meta; int f; if ((f = get_last_md_by_name(c, name, &lmd)) < 0) return -1; if (!f) return 0; if ((f = get_meta_by_name_md(c, name, &lmd, &meta)) < 0) return -1; if (!f) { fprintf(stderr, "Database inconsistency\n"); return -1; } if (meta.last_seen != c->version) return 0; memcpy(md, &lmd, sizeof(struct syrep_md)); return 1; } uint32_t get_version_timestamp(struct syrep_db_context *c, uint32_t v) { DBT key, data; struct syrep_version version; struct syrep_timestamp *timestamp; int ret; assert(c && c->db_version_timestamp); if (v > c->version) return time(NULL); if (v <= 0) v = 1; memset(&version, 0, sizeof(version)); version.v = v; memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.data = &version; key.size = sizeof(version); if ((ret = c->db_version_timestamp->get(c->db_version_timestamp, NULL, &key, &data, 0))) { c->db_version_timestamp->err(c->db_version_timestamp, ret, "version_timestamp::get"); return (uint32_t) -1; } timestamp = (struct syrep_timestamp*) data.data; assert(timestamp); return timestamp->t; }