/* * returns: * -ENOMEM: out of memory * -EINVAL: invalid args * -EIO: if any prepare statement fails * OSD_OK: success */ int coll_initialize(void *db) { int ret = 0; int sqlret = 0; char SQL[MAXSQLEN]; struct db_context *dbc = (struct db_context *)db; if (dbc == NULL || dbc->db == NULL) { ret = -EINVAL; goto out; } if (dbc->coll != NULL) { if (strcmp(dbc->coll->name, coll_tab_name) != 0) { ret = -EINVAL; goto out; } else { coll_finalize(dbc); } } dbc->coll = Calloc(1, sizeof(*dbc->coll)); if (!dbc->coll) { ret = -ENOMEM; goto out; } dbc->coll->name = strdup(coll_tab_name); if (!dbc->coll->name) { ret = -ENOMEM; goto out; } sprintf(SQL, "INSERT INTO %s VALUES (?, ?, ?, ?);", dbc->coll->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->coll->insert, NULL); if (ret != SQLITE_OK) goto out_finalize_insert; sprintf(SQL, "DELETE FROM %s WHERE pid = ? AND cid = ? AND oid = ?;", dbc->coll->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->coll->delete, NULL); if (ret != SQLITE_OK) goto out_finalize_delete; sprintf(SQL, "DELETE FROM %s WHERE pid = ? AND cid = ?;", dbc->coll->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->coll->delcid, NULL); if (ret != SQLITE_OK) goto out_finalize_delcid; sprintf(SQL, "DELETE FROM %s WHERE pid = ? AND oid = ?;", dbc->coll->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->coll->deloid, NULL); if (ret != SQLITE_OK) goto out_finalize_deloid; sprintf(SQL, "SELECT COUNT (*) FROM %s WHERE pid = ? AND cid = ? " " LIMIT 1;", dbc->coll->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->coll->emptycid, NULL); if (ret != SQLITE_OK) goto out_finalize_emptycid; sprintf(SQL, "SELECT cid FROM %s WHERE pid = ? AND oid = ? AND " " number = ?;", dbc->coll->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->coll->getcid, NULL); if (ret != SQLITE_OK) goto out_finalize_getcid; sprintf(SQL, "SELECT oid FROM %s WHERE pid = ? AND cid = ? AND " " oid >= ?;", dbc->coll->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->coll->getoids, NULL); if (ret != SQLITE_OK) goto out_finalize_getoids; sprintf(SQL, "INSERT INTO %s SELECT ?, ?, oid, 0 FROM %s WHERE " "pid = ? AND cid = ?;", dbc->coll->name, dbc->coll->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->coll->copyoids, NULL); if (ret != SQLITE_OK) goto out_finalize_copyoids; ret = OSD_OK; /* success */ goto out; out_finalize_copyoids: db_sqfinalize(dbc->db, dbc->coll->copyoids, SQL); SQL[0] = '\0'; out_finalize_getoids: db_sqfinalize(dbc->db, dbc->coll->getoids, SQL); SQL[0] = '\0'; out_finalize_getcid: db_sqfinalize(dbc->db, dbc->coll->getcid, SQL); SQL[0] = '\0'; out_finalize_emptycid: db_sqfinalize(dbc->db, dbc->coll->emptycid, SQL); SQL[0] = '\0'; out_finalize_deloid: db_sqfinalize(dbc->db, dbc->coll->deloid, SQL); SQL[0] = '\0'; out_finalize_delcid: db_sqfinalize(dbc->db, dbc->coll->delcid, SQL); SQL[0] = '\0'; out_finalize_delete: db_sqfinalize(dbc->db, dbc->coll->delete, SQL); SQL[0] = '\0'; out_finalize_insert: db_sqfinalize(dbc->db, dbc->coll->insert, SQL); ret = -EIO; out: return ret; }
/* * 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; }
/* * returns: * -ENOMEM: out of memory * -EINVAL: invalid args * -EIO: if any prepare statement fails * OSD_OK: success */ int obj_initialize(void *db) { int ret = 0; int sqlret = 0; char SQL[MAXSQLEN]; struct db_context *dbc = (struct db_context*)db; if (dbc == NULL || dbc->db == NULL) { ret = -EINVAL; goto out; } if (dbc->obj != NULL) { if (strcmp(dbc->obj->name, obj_tab_name) != 0) { ret = -EINVAL; goto out; } else { obj_finalize(dbc); } } dbc->obj = Calloc(1, sizeof(*dbc->obj)); if (!dbc->obj) { ret = -ENOMEM; goto out; } dbc->obj->name = strdup(obj_tab_name); if (!dbc->obj->name) { ret = -ENOMEM; goto out; } sprintf(SQL, "INSERT INTO %s VALUES (?, ?, ?);", dbc->obj->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->insert, NULL); if (ret != SQLITE_OK) goto out_finalize_insert; sprintf(SQL, "DELETE FROM %s WHERE pid = ? AND oid = ?;", dbc->obj->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->delete, NULL); if (ret != SQLITE_OK) goto out_finalize_delete; sprintf(SQL, "DELETE FROM %s WHERE pid = ?;", dbc->obj->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->delpid, NULL); if (ret != SQLITE_OK) goto out_finalize_delpid; sprintf(SQL, "SELECT MAX(oid) FROM %s WHERE pid = ?;", dbc->obj->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->nextoid, NULL); if (ret != SQLITE_OK) goto out_finalize_nextoid; sprintf(SQL, "SELECT MAX(pid) FROM %s;", dbc->obj->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->nextpid, NULL); if (ret != SQLITE_OK) goto out_finalize_nextpid; sprintf(SQL, "SELECT COUNT(oid) FROM %s WHERE pid = ? AND oid = ?;", dbc->obj->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->isprsnt, NULL); if (ret != SQLITE_OK) goto out_finalize_isprsnt; sprintf(SQL, "SELECT COUNT(oid) FROM %s WHERE pid = ? AND oid != 0 " " LIMIT 1;", dbc->obj->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->emptypid, NULL); if (ret != SQLITE_OK) goto out_finalize_emptypid; sprintf(SQL, "SELECT type FROM %s WHERE pid = ? AND oid = ?;", dbc->obj->name); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->gettype, NULL); if (ret != SQLITE_OK) goto out_finalize_gettype; sprintf(SQL, "SELECT oid FROM %s WHERE pid = ? AND type = %u AND " " oid >= ?;", dbc->obj->name, USEROBJECT); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->getoids, NULL); if (ret != SQLITE_OK) goto out_finalize_getoids; sprintf(SQL, "SELECT oid FROM %s WHERE pid = ? AND type = %u AND " " oid >= ?;", dbc->obj->name, COLLECTION); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->getcids, NULL); if (ret != SQLITE_OK) goto out_finalize_getcids; sprintf(SQL, "SELECT pid FROM %s WHERE oid = %llu AND type = %u AND " " pid >= ?;", dbc->obj->name, llu(PARTITION_OID), PARTITION); ret = sqlite3_prepare(dbc->db, SQL, -1, &dbc->obj->getpids, NULL); if (ret != SQLITE_OK) goto out_finalize_getpids; ret = OSD_OK; /* success */ goto out; out_finalize_getpids: db_sqfinalize(dbc->db, dbc->obj->getpids, SQL); SQL[0] = '\0'; out_finalize_getcids: db_sqfinalize(dbc->db, dbc->obj->getcids, SQL); SQL[0] = '\0'; out_finalize_getoids: db_sqfinalize(dbc->db, dbc->obj->getoids, SQL); SQL[0] = '\0'; out_finalize_gettype: db_sqfinalize(dbc->db, dbc->obj->gettype, SQL); SQL[0] = '\0'; out_finalize_emptypid: db_sqfinalize(dbc->db, dbc->obj->emptypid, SQL); SQL[0] = '\0'; out_finalize_isprsnt: db_sqfinalize(dbc->db, dbc->obj->isprsnt, SQL); SQL[0] = '\0'; out_finalize_nextpid: db_sqfinalize(dbc->db, dbc->obj->nextpid, SQL); SQL[0] = '\0'; out_finalize_nextoid: db_sqfinalize(dbc->db, dbc->obj->nextoid, SQL); SQL[0] = '\0'; out_finalize_delpid: db_sqfinalize(dbc->db, dbc->obj->delpid, SQL); SQL[0] = '\0'; out_finalize_delete: db_sqfinalize(dbc->db, dbc->obj->delete, SQL); SQL[0] = '\0'; out_finalize_insert: db_sqfinalize(dbc->db, dbc->obj->insert, SQL); ret = -EIO; out: return ret; }