int db_initialize(struct db_context *dbc) { int ret = 0; if (dbc == NULL) { ret = -EINVAL; goto out; } ret = coll_initialize(dbc); if (ret != OSD_OK) goto finalize_coll; ret = obj_initialize(dbc); if (ret != OSD_OK) goto finalize_obj; ret = attr_initialize(dbc); if (ret != OSD_OK) goto finalize_attr; ret = OSD_OK; goto out; finalize_attr: attr_finalize(dbc); finalize_obj: obj_finalize(dbc); finalize_coll: coll_finalize(dbc); out: return ret; }
int db_finalize(struct db_context *dbc) { int ret = 0; if (dbc == NULL) return -EINVAL; ret = 0; ret |= coll_finalize(dbc); ret |= obj_finalize(dbc); ret |= attr_finalize(dbc); if (ret == OSD_OK) return OSD_OK; return OSD_ERROR; }
/* * returns: * -ENOMEM: out of memory * -EINVAL: invalid args * -EIO: if any prepare statement fails * OSD_OK: success */ int attr_initialize(struct db_context *dbc) { int ret = 0; int sqlret = 0; char SQL[MAXSQLEN]; if (dbc == NULL || dbc->db == NULL) { ret = -EINVAL; goto out; } if (dbc->attr != NULL) { if (strcmp(dbc->attr->name, attr_tab_name) != 0) { ret = -EINVAL; goto out; } else { attr_finalize(dbc); } } dbc->attr = Calloc(1, sizeof(*dbc->attr)); if (!dbc->attr) { ret = -ENOMEM; goto out; } dbc->attr->name = strdup(attr_tab_name); if (!dbc->attr->name) { ret = -ENOMEM; goto out; } sprintf(SQL, "INSERT OR REPLACE INTO %s VALUES (?, ?, ?, ?, ?);", dbc->attr->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->attr->setattr, NULL); if (ret != SQLITE_OK) goto out_finalize_setattr; sprintf(SQL, "DELETE FROM %s WHERE pid = ? AND oid = ? AND page = ? " " AND number = ?;", dbc->attr->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->attr->delattr, NULL); if (ret != SQLITE_OK) goto out_finalize_delattr; sprintf(SQL, "DELETE FROM %s WHERE pid = ? AND oid = ?;", dbc->attr->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->attr->delall, NULL); if (ret != SQLITE_OK) goto out_finalize_delall; sprintf(SQL, "SELECT page, number, value FROM %s WHERE pid = ? AND " " oid = ? AND page = ? AND number = ?;", dbc->attr->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->attr->getattr, NULL); if (ret != SQLITE_OK) goto out_finalize_getattr; sprintf(SQL, "SELECT value FROM %s WHERE pid = ? AND oid = ? AND " " page = ? AND number = ?;", dbc->attr->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->attr->getval, NULL); if (ret != SQLITE_OK) goto out_finalize_getval; sprintf(SQL, "SELECT page, number, value FROM %s WHERE pid = ? AND " " oid = ? AND page = ?;", dbc->attr->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->attr->pgaslst, NULL); if (ret != SQLITE_OK) goto out_finalize_pgaslst; sprintf(SQL, "SELECT page, number, value FROM %s WHERE pid = ? AND " " oid = ? AND number = ?;", dbc->attr->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->attr->forallpg, NULL); if (ret != SQLITE_OK) goto out_finalize_forallpg; sprintf(SQL, "SELECT page, number, value FROM %s WHERE pid = ? AND " "oid = ?;", dbc->attr->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->attr->getall, NULL); if (ret != SQLITE_OK) goto out_finalize_getall; /* * We need to compute the directory page since we don't maintain any. * This SQL statement is inefficient. Its complexity is O(N) where * 'N' is the total number of defined attributes of the object. * Further the statement executes 3 iterations over all the * attributes of the object, hence the constant term is also * significant. There is some advantage in adding an index on * (pid,oid,number) but that will hit performance of insertions and * deletions which are more critical than dirpage. */ sprintf(SQL, " SELECT page, @uip FROM %s" " WHERE pid = @pid AND oid = @oid GROUP BY page " " EXCEPT " " SELECT page, @uip FROM attr " " WHERE pid = @pid AND oid = @oid AND number = 0 " " UNION ALL " " SELECT page, value FROM attr " " WHERE pid = @pid AND oid = @oid AND number = 0;", dbc->attr->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->attr->dirpage, NULL); if (ret != SQLITE_OK) goto out_finalize_dirpage; ret = OSD_OK; /* success */ goto out; out_finalize_dirpage: db_sqfinalize(dbc->db, dbc->attr->dirpage, SQL); SQL[0] = '\0'; out_finalize_getall: db_sqfinalize(dbc->db, dbc->attr->getall, SQL); SQL[0] = '\0'; out_finalize_forallpg: db_sqfinalize(dbc->db, dbc->attr->forallpg, SQL); SQL[0] = '\0'; out_finalize_pgaslst: db_sqfinalize(dbc->db, dbc->attr->pgaslst, SQL); SQL[0] = '\0'; out_finalize_getval: db_sqfinalize(dbc->db, dbc->attr->getval, SQL); SQL[0] = '\0'; out_finalize_getattr: db_sqfinalize(dbc->db, dbc->attr->getattr, SQL); SQL[0] = '\0'; out_finalize_delall: db_sqfinalize(dbc->db, dbc->attr->delall, SQL); SQL[0] = '\0'; out_finalize_delattr: db_sqfinalize(dbc->db, dbc->attr->delattr, SQL); SQL[0] = '\0'; out_finalize_setattr: db_sqfinalize(dbc->db, dbc->attr->setattr, SQL); ret = -EIO; out: return ret; }