From: Soumya Koduri Date: Tue, 19 Oct 2021 17:57:56 +0000 (+0530) Subject: rgw/dbstore: LC APIs definition X-Git-Tag: v17.1.0~418^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F43433%2Fhead;p=ceph.git rgw/dbstore: LC APIs definition Implement methods to add & fetch LCEntries in dbstore. Signed-off-by: Soumya Koduri --- diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index 424a32816d0c..d48b2a395e73 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -1188,39 +1188,39 @@ namespace rgw::sal { int DBLifecycle::get_entry(const std::string& oid, const std::string& marker, LCEntry& entry) { - return 0; + return store->getDB()->get_entry(oid, marker, entry); } int DBLifecycle::get_next_entry(const std::string& oid, std::string& marker, LCEntry& entry) { - return 0; + return store->getDB()->get_next_entry(oid, marker, entry); } int DBLifecycle::set_entry(const std::string& oid, const LCEntry& entry) { - return 0; + return store->getDB()->set_entry(oid, entry); } int DBLifecycle::list_entries(const std::string& oid, const std::string& marker, uint32_t max_entries, vector& entries) { - return 0; + return store->getDB()->list_entries(oid, marker, max_entries, entries); } int DBLifecycle::rm_entry(const std::string& oid, const LCEntry& entry) { - return 0; + return store->getDB()->rm_entry(oid, entry); } int DBLifecycle::get_head(const std::string& oid, LCHead& head) { - return 0; + return store->getDB()->get_head(oid, head); } int DBLifecycle::put_head(const std::string& oid, const LCHead& head) { - return 0; + return store->getDB()->put_head(oid, head); } LCSerializer* DBLifecycle::get_serializer(const std::string& lock_name, const std::string& oid, const std::string& cookie) diff --git a/src/rgw/store/dbstore/common/dbstore.cc b/src/rgw/store/dbstore/common/dbstore.cc index c771763ff7f0..1b851fa550cf 100644 --- a/src/rgw/store/dbstore/common/dbstore.cc +++ b/src/rgw/store/dbstore/common/dbstore.cc @@ -143,6 +143,20 @@ DBOp *DB::getDBOp(const DoutPrefixProvider *dpp, string Op, struct DBOpParams *p return dbops.GetBucket; if (!Op.compare("ListUserBuckets")) return dbops.ListUserBuckets; + if (!Op.compare("InsertLCEntry")) + return dbops.InsertLCEntry; + if (!Op.compare("RemoveLCEntry")) + return dbops.RemoveLCEntry; + if (!Op.compare("GetLCEntry")) + return dbops.GetLCEntry; + if (!Op.compare("ListLCEntries")) + return dbops.ListLCEntries; + if (!Op.compare("InsertLCHead")) + return dbops.InsertLCHead; + if (!Op.compare("RemoveLCHead")) + return dbops.RemoveLCHead; + if (!Op.compare("GetLCHead")) + return dbops.GetLCHead; /* Object Operations */ map::iterator iter; @@ -240,6 +254,8 @@ int DB::InitializeParams(const DoutPrefixProvider *dpp, string Op, DBOpParams *p //reset params here params->user_table = user_table; params->bucket_table = bucket_table; + params->lc_entry_table = lc_entry_table; + params->lc_head_table = lc_head_table; ret = 0; out: @@ -1731,5 +1747,180 @@ out: return ret; } +int DB::get_entry(const std::string& oid, const std::string& marker, + rgw::sal::Lifecycle::LCEntry& entry) +{ + int ret = 0; + const DoutPrefixProvider *dpp = get_def_dpp(); + + DBOpParams params = {}; + InitializeParams(dpp, "GetLCEntry", ¶ms); + + params.op.lc_entry.index = oid; + params.op.lc_entry.entry.bucket = marker; + + params.op.query_str = "get_entry"; + ret = ProcessOp(dpp, "GetLCEntry", ¶ms); + + if (ret) { + ldpp_dout(dpp, 0)<<"In GetLCEntry failed err:(" <& entries) +{ + int ret = 0; + const DoutPrefixProvider *dpp = get_def_dpp(); + + entries.clear(); + + DBOpParams params = {}; + InitializeParams(dpp, "ListLCEntries", ¶ms); + + params.op.lc_entry.index = oid; + params.op.lc_entry.min_marker = marker; + params.op.list_max_count = max_entries; + + ret = ProcessOp(dpp, "ListLCEntries", ¶ms); + + if (ret) { + ldpp_dout(dpp, 0)<<"In ListLCEntries failed err:(" < list_entries; +}; + struct DBOpInfo { string name; // Op name /* Support only single access_key for now. So store @@ -110,6 +123,8 @@ struct DBOpInfo { DBOpBucketInfo bucket; DBOpObjectInfo obj; DBOpObjectDataInfo obj_data; + DBOpLCHeadInfo lc_head; + DBOpLCEntryInfo lc_entry; uint64_t list_max_count; }; @@ -272,12 +287,28 @@ struct DBOpObjectDataPrepareInfo { string multipart_part_num = ":multipart_part_num"; }; +struct DBOpLCEntryPrepareInfo { + string index = ":index"; + string bucket_name = ":bucket_name"; + string start_time = ":start_time"; + string status = ":status"; + string min_marker = ":min_marker"; +}; + +struct DBOpLCHeadPrepareInfo { + string index = ":index"; + string start_date = ":start_date"; + string marker = ":marker"; +}; + struct DBOpPrepareInfo { DBOpUserPrepareInfo user; string query_str = ":query_str"; DBOpBucketPrepareInfo bucket; DBOpObjectPrepareInfo obj; DBOpObjectDataPrepareInfo obj_data; + DBOpLCHeadPrepareInfo lc_head; + DBOpLCEntryPrepareInfo lc_entry; string list_max_count = ":list_max_count"; }; @@ -307,6 +338,13 @@ struct DBOps { class RemoveBucketOp *RemoveBucket; class GetBucketOp *GetBucket; class ListUserBucketsOp *ListUserBuckets; + class InsertLCEntryOp *InsertLCEntry; + class RemoveLCEntryOp *RemoveLCEntry; + class GetLCEntryOp *GetLCEntry; + class ListLCEntriesOp *ListLCEntries; + class InsertLCHeadOp *InsertLCHead; + class RemoveLCHeadOp *RemoveLCHead; + class GetLCHeadOp *GetLCHead; }; class ObjectOp { @@ -549,22 +587,21 @@ class DBOp { const string CreateLCEntryTableQ = "CREATE TABLE IF NOT EXISTS '{}' ( \ - LCIndex TEXT NOT NULL, \ + LCIndex TEXT NOT NULL , \ BucketName TEXT NOT NULL , \ StartTime INTEGER , \ - Status INTEGER, \ + Status INTEGER , \ PRIMARY KEY (LCIndex, BucketName), \ FOREIGN KEY (BucketName) \ REFERENCES '{}' (BucketName) ON DELETE CASCADE ON UPDATE CASCADE \n);"; const string CreateLCHeadTableQ = "CREATE TABLE IF NOT EXISTS '{}' ( \ - LCIndex TEXT NOT NULL, \ - Marker TEXT, \ + LCIndex TEXT NOT NULL , \ + Marker TEXT , \ StartDate INTEGER , \ PRIMARY KEY (LCIndex) \n);"; - const string DropQ = "DROP TABLE IF EXISTS '{}'"; const string ListAllQ = "SELECT * from '{}'"; @@ -1140,6 +1177,122 @@ class DeleteObjectDataOp: public DBOp { } }; +class InsertLCEntryOp: public DBOp { + private: + const string Query = + "INSERT OR REPLACE INTO '{}' \ + (LCIndex, BucketName, StartTime, Status) \ + VALUES ({}, {}, {}, {})"; + + public: + virtual ~InsertLCEntryOp() {} + + string Schema(DBOpPrepareParams ¶ms) { + return fmt::format(Query.c_str(), params.lc_entry_table.c_str(), + params.op.lc_entry.index, params.op.lc_entry.bucket_name, + params.op.lc_entry.start_time, params.op.lc_entry.status); + } +}; + +class RemoveLCEntryOp: public DBOp { + private: + const string Query = + "DELETE from '{}' where LCIndex = {} and BucketName = {}"; + + public: + virtual ~RemoveLCEntryOp() {} + + string Schema(DBOpPrepareParams ¶ms) { + return fmt::format(Query.c_str(), params.lc_entry_table.c_str(), + params.op.lc_entry.index, params.op.lc_entry.bucket_name); + } +}; + +class GetLCEntryOp: public DBOp { + private: + const string Query = "SELECT \ + LCIndex, BucketName, StartTime, Status \ + from '{}' where LCIndex = {} and BucketName = {}"; + const string NextQuery = "SELECT \ + LCIndex, BucketName, StartTime, Status \ + from '{}' where LCIndex = {} and BucketName > {} ORDER BY BucketName ASC"; + + public: + virtual ~GetLCEntryOp() {} + + string Schema(DBOpPrepareParams ¶ms) { + if (params.op.query_str == "get_next_entry") { + return fmt::format(NextQuery.c_str(), params.lc_entry_table.c_str(), + params.op.lc_entry.index, params.op.lc_entry.bucket_name); + } + // default + return fmt::format(Query.c_str(), params.lc_entry_table.c_str(), + params.op.lc_entry.index, params.op.lc_entry.bucket_name); + } +}; + +class ListLCEntriesOp: public DBOp { + private: + const string Query = "SELECT \ + LCIndex, BucketName, StartTime, Status \ + FROM '{}' WHERE LCIndex = {} AND BucketName > {} ORDER BY BucketName ASC LIMIT {}"; + + public: + virtual ~ListLCEntriesOp() {} + + string Schema(DBOpPrepareParams ¶ms) { + return fmt::format(Query.c_str(), params.lc_entry_table.c_str(), + params.op.lc_entry.index.c_str(), params.op.lc_entry.min_marker.c_str(), + params.op.list_max_count.c_str()); + } +}; + +class InsertLCHeadOp: public DBOp { + private: + const string Query = + "INSERT OR REPLACE INTO '{}' \ + (LCIndex, Marker, StartDate) \ + VALUES ({}, {}, {})"; + + public: + virtual ~InsertLCHeadOp() {} + + string Schema(DBOpPrepareParams ¶ms) { + return fmt::format(Query.c_str(), params.lc_head_table.c_str(), + params.op.lc_head.index, params.op.lc_head.marker, + params.op.lc_head.start_date); + } +}; + +class RemoveLCHeadOp: public DBOp { + private: + const string Query = + "DELETE from '{}' where LCIndex = {}"; + + public: + virtual ~RemoveLCHeadOp() {} + + string Schema(DBOpPrepareParams ¶ms) { + return fmt::format(Query.c_str(), params.lc_head_table.c_str(), + params.op.lc_head.index); + } +}; + +class GetLCHeadOp: public DBOp { + private: + const string Query = "SELECT \ + LCIndex, Marker, StartDate \ + from '{}' where LCIndex = {}"; + + public: + virtual ~GetLCHeadOp() {} + + string Schema(DBOpPrepareParams ¶ms) { + return fmt::format(Query.c_str(), params.lc_head_table.c_str(), + params.op.lc_head.index); + } +}; + /* taken from rgw_rados.h::RGWOLHInfo */ struct DBOLHInfo { rgw_obj target; @@ -1621,6 +1774,17 @@ class DB { const raw_obj& read_obj, off_t obj_ofs, off_t len, bool is_head_obj, RGWObjState *astate, void *arg); + + int get_entry(const std::string& oid, const std::string& marker, + rgw::sal::Lifecycle::LCEntry& entry); + int get_next_entry(const std::string& oid, std::string& marker, + rgw::sal::Lifecycle::LCEntry& entry); + int set_entry(const std::string& oid, const rgw::sal::Lifecycle::LCEntry& entry); + int list_entries(const std::string& oid, const std::string& marker, + uint32_t max_entries, std::vector& entries); + int rm_entry(const std::string& oid, const rgw::sal::Lifecycle::LCEntry& entry); + int get_head(const std::string& oid, rgw::sal::Lifecycle::LCHead& head); + int put_head(const std::string& oid, const rgw::sal::Lifecycle::LCHead& head); }; struct db_get_obj_data { diff --git a/src/rgw/store/dbstore/sqlite/sqliteDB.cc b/src/rgw/store/dbstore/sqlite/sqliteDB.cc index 389fd0d5fba1..dc5463f5b09f 100644 --- a/src/rgw/store/dbstore/sqlite/sqliteDB.cc +++ b/src/rgw/store/dbstore/sqlite/sqliteDB.cc @@ -274,6 +274,19 @@ enum GetObjectData { MultipartPartNum }; +enum GetLCEntry { + LCEntryIndex, + LCEntryBucketName, + LCEntryStartTime, + LCEntryStatus +}; + +enum GetLCHead { + LCHeadIndex, + LCHeadMarker, + LCHeadStartDate +}; + static int list_user(const DoutPrefixProvider *dpp, DBOpInfo &op, sqlite3_stmt *stmt) { if (!stmt) return -1; @@ -474,6 +487,32 @@ static int get_objectdata(const DoutPrefixProvider *dpp, DBOpInfo &op, sqlite3_s return 0; } +static int list_lc_entry(const DoutPrefixProvider *dpp, DBOpInfo &op, sqlite3_stmt *stmt) { + if (!stmt) + return -1; + + op.lc_entry.index = (const char*)sqlite3_column_text(stmt, LCEntryIndex); + op.lc_entry.entry.bucket = (const char*)sqlite3_column_text(stmt, LCEntryBucketName); + op.lc_entry.entry.start_time = sqlite3_column_int(stmt, LCEntryStartTime); + op.lc_entry.entry.status = sqlite3_column_int(stmt, LCEntryStatus); + + op.lc_entry.list_entries.push_back(op.lc_entry.entry); + + return 0; +} + +static int list_lc_head(const DoutPrefixProvider *dpp, DBOpInfo &op, sqlite3_stmt *stmt) { + if (!stmt) + return -1; + + op.lc_head.index = (const char*)sqlite3_column_text(stmt, LCHeadIndex); + op.lc_head.head.marker = (const char*)sqlite3_column_text(stmt, LCHeadMarker); + + SQL_DECODE_BLOB_PARAM(dpp, stmt, LCHeadStartDate, op.lc_head.head.start_date, sdb); + + return 0; +} + int SQLiteDB::InitializeDBOps(const DoutPrefixProvider *dpp) { (void)createTables(dpp); @@ -485,6 +524,13 @@ int SQLiteDB::InitializeDBOps(const DoutPrefixProvider *dpp) dbops.RemoveBucket = new SQLRemoveBucket(&this->db, this->getDBname(), cct); dbops.GetBucket = new SQLGetBucket(&this->db, this->getDBname(), cct); dbops.ListUserBuckets = new SQLListUserBuckets(&this->db, this->getDBname(), cct); + dbops.InsertLCEntry = new SQLInsertLCEntry(&this->db, this->getDBname(), cct); + dbops.RemoveLCEntry = new SQLRemoveLCEntry(&this->db, this->getDBname(), cct); + dbops.GetLCEntry = new SQLGetLCEntry(&this->db, this->getDBname(), cct); + dbops.ListLCEntries = new SQLListLCEntries(&this->db, this->getDBname(), cct); + dbops.InsertLCHead = new SQLInsertLCHead(&this->db, this->getDBname(), cct); + dbops.RemoveLCHead = new SQLRemoveLCHead(&this->db, this->getDBname(), cct); + dbops.GetLCHead = new SQLGetLCHead(&this->db, this->getDBname(), cct); return 0; } @@ -499,6 +545,13 @@ int SQLiteDB::FreeDBOps(const DoutPrefixProvider *dpp) delete dbops.RemoveBucket; delete dbops.GetBucket; delete dbops.ListUserBuckets; + delete dbops.InsertLCEntry; + delete dbops.RemoveLCEntry; + delete dbops.GetLCEntry; + delete dbops.ListLCEntries; + delete dbops.InsertLCHead; + delete dbops.RemoveLCHead; + delete dbops.GetLCHead; return 0; } @@ -2386,3 +2439,332 @@ int SQLDeleteObjectData::Execute(const DoutPrefixProvider *dpp, struct DBOpParam out: return ret; } + +int SQLInsertLCEntry::Prepare(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + struct DBOpPrepareParams p_params = PrepareParams; + + if (!*sdb) { + ldpp_dout(dpp, 0)<<"In SQLInsertLCEntry - no db" << dendl; + goto out; + } + + p_params.lc_entry_table = params->lc_entry_table; + + SQL_PREPARE(dpp, p_params, sdb, stmt, ret, "PrepareInsertLCEntry"); + +out: + return ret; +} + +int SQLInsertLCEntry::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int index = -1; + int rc = 0; + struct DBOpPrepareParams p_params = PrepareParams; + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.index.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_entry.index.c_str(), sdb); + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.bucket_name.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_entry.entry.bucket.c_str(), sdb); + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.status.c_str(), sdb); + SQL_BIND_INT(dpp, stmt, index, params->op.lc_entry.entry.status, sdb); + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.start_time.c_str(), sdb); + SQL_BIND_INT(dpp, stmt, index, params->op.lc_entry.entry.start_time, sdb); + +out: + return rc; +} + +int SQLInsertLCEntry::Execute(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + + SQL_EXECUTE(dpp, params, stmt, NULL); +out: + return ret; +} + +int SQLRemoveLCEntry::Prepare(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + struct DBOpPrepareParams p_params = PrepareParams; + + if (!*sdb) { + ldpp_dout(dpp, 0)<<"In SQLRemoveLCEntry - no db" << dendl; + goto out; + } + + p_params.lc_entry_table = params->lc_entry_table; + + SQL_PREPARE(dpp, p_params, sdb, stmt, ret, "PrepareRemoveLCEntry"); + +out: + return ret; +} + +int SQLRemoveLCEntry::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int index = -1; + int rc = 0; + struct DBOpPrepareParams p_params = PrepareParams; + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.index.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_entry.index.c_str(), sdb); + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.bucket_name.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_entry.entry.bucket.c_str(), sdb); + +out: + return rc; +} + +int SQLRemoveLCEntry::Execute(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + + SQL_EXECUTE(dpp, params, stmt, NULL); +out: + return ret; +} + +int SQLGetLCEntry::Prepare(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + sqlite3_stmt** pstmt = NULL; // Prepared statement + struct DBOpPrepareParams p_params = PrepareParams; + + if (!*sdb) { + ldpp_dout(dpp, 0)<<"In SQLGetLCEntry - no db" << dendl; + goto out; + } + + p_params.lc_entry_table = params->lc_entry_table; + p_params.op.query_str = params->op.query_str; + + if (params->op.query_str == "get_next_entry") { + pstmt = &next_stmt; + } else { + pstmt = &stmt; + } + SQL_PREPARE(dpp, p_params, sdb, *pstmt, ret, "PrepareGetLCEntry"); + +out: + return ret; +} + +int SQLGetLCEntry::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int index = -1; + int rc = 0; + struct DBOpPrepareParams p_params = PrepareParams; + sqlite3_stmt** pstmt = NULL; // Prepared statement + + if (params->op.query_str == "get_next_entry") { + pstmt = &next_stmt; + } else { + pstmt = &stmt; + } + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.index.c_str(), sdb); + SQL_BIND_TEXT(dpp, *pstmt, index, params->op.lc_entry.index.c_str(), sdb); + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.bucket_name.c_str(), sdb); + SQL_BIND_TEXT(dpp, *pstmt, index, params->op.lc_entry.entry.bucket.c_str(), sdb); + +out: + return rc; +} + +int SQLGetLCEntry::Execute(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + sqlite3_stmt** pstmt = NULL; // Prepared statement + + if (params->op.query_str == "get_next_entry") { + pstmt = &next_stmt; + } else { + pstmt = &stmt; + } + + SQL_EXECUTE(dpp, params, *pstmt, list_lc_entry); +out: + return ret; +} + +int SQLListLCEntries::Prepare(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + struct DBOpPrepareParams p_params = PrepareParams; + + if (!*sdb) { + ldpp_dout(dpp, 0)<<"In SQLListLCEntries - no db" << dendl; + goto out; + } + + p_params.lc_entry_table = params->lc_entry_table; + + SQL_PREPARE(dpp, p_params, sdb, stmt, ret, "PrepareListLCEntries"); + +out: + return ret; +} + +int SQLListLCEntries::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int index = -1; + int rc = 0; + struct DBOpPrepareParams p_params = PrepareParams; + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.index.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_entry.index.c_str(), sdb); + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_entry.min_marker.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_entry.min_marker.c_str(), sdb); + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.list_max_count.c_str(), sdb); + SQL_BIND_INT(dpp, stmt, index, params->op.list_max_count, sdb); + +out: + return rc; +} + +int SQLListLCEntries::Execute(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + + SQL_EXECUTE(dpp, params, stmt, list_lc_entry); +out: + return ret; +} + +int SQLInsertLCHead::Prepare(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + struct DBOpPrepareParams p_params = PrepareParams; + + if (!*sdb) { + ldpp_dout(dpp, 0)<<"In SQLInsertLCHead - no db" << dendl; + goto out; + } + + p_params.lc_head_table = params->lc_head_table; + + SQL_PREPARE(dpp, p_params, sdb, stmt, ret, "PrepareInsertLCHead"); + +out: + return ret; +} + +int SQLInsertLCHead::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int index = -1; + int rc = 0; + struct DBOpPrepareParams p_params = PrepareParams; + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_head.index.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_head.index.c_str(), sdb); + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_head.marker.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_head.head.marker.c_str(), sdb); + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_head.start_date.c_str(), sdb); + SQL_ENCODE_BLOB_PARAM(dpp, stmt, index, params->op.lc_head.head.start_date, sdb); + +out: + return rc; +} + +int SQLInsertLCHead::Execute(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + + SQL_EXECUTE(dpp, params, stmt, NULL); +out: + return ret; +} + +int SQLRemoveLCHead::Prepare(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + struct DBOpPrepareParams p_params = PrepareParams; + + if (!*sdb) { + ldpp_dout(dpp, 0)<<"In SQLRemoveLCHead - no db" << dendl; + goto out; + } + + p_params.lc_head_table = params->lc_head_table; + + SQL_PREPARE(dpp, p_params, sdb, stmt, ret, "PrepareRemoveLCHead"); + +out: + return ret; +} + +int SQLRemoveLCHead::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int index = -1; + int rc = 0; + struct DBOpPrepareParams p_params = PrepareParams; + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_head.index.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_head.index.c_str(), sdb); + +out: + return rc; +} + +int SQLRemoveLCHead::Execute(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + + SQL_EXECUTE(dpp, params, stmt, NULL); +out: + return ret; +} + +int SQLGetLCHead::Prepare(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + struct DBOpPrepareParams p_params = PrepareParams; + + if (!*sdb) { + ldpp_dout(dpp, 0)<<"In SQLGetLCHead - no db" << dendl; + goto out; + } + + p_params.lc_head_table = params->lc_head_table; + + SQL_PREPARE(dpp, p_params, sdb, stmt, ret, "PrepareGetLCHead"); + +out: + return ret; +} + +int SQLGetLCHead::Bind(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int index = -1; + int rc = 0; + struct DBOpPrepareParams p_params = PrepareParams; + + SQL_BIND_INDEX(dpp, stmt, index, p_params.op.lc_head.index.c_str(), sdb); + SQL_BIND_TEXT(dpp, stmt, index, params->op.lc_head.index.c_str(), sdb); + +out: + return rc; +} + +int SQLGetLCHead::Execute(const DoutPrefixProvider *dpp, struct DBOpParams *params) +{ + int ret = -1; + + // clear the params before fetching the entry + params->op.lc_head.head = {}; + SQL_EXECUTE(dpp, params, stmt, list_lc_head); +out: + return ret; +} diff --git a/src/rgw/store/dbstore/sqlite/sqliteDB.h b/src/rgw/store/dbstore/sqlite/sqliteDB.h index 5d747f7a5745..55e3dc33aa34 100644 --- a/src/rgw/store/dbstore/sqlite/sqliteDB.h +++ b/src/rgw/store/dbstore/sqlite/sqliteDB.h @@ -376,4 +376,120 @@ class SQLDeleteObjectData : public SQLiteDB, public DeleteObjectDataOp { int Execute(const DoutPrefixProvider *dpp, DBOpParams *params); int Bind(const DoutPrefixProvider *dpp, DBOpParams *params); }; + +class SQLInsertLCEntry : public SQLiteDB, public InsertLCEntryOp { + private: + sqlite3 **sdb = NULL; + sqlite3_stmt *stmt = NULL; // Prepared statement + + public: + SQLInsertLCEntry(void **db, string db_name, CephContext *cct) : SQLiteDB((sqlite3 *)(*db), db_name, cct), sdb((sqlite3 **)db) {} + ~SQLInsertLCEntry() { + if (stmt) + sqlite3_finalize(stmt); + } + int Prepare(const DoutPrefixProvider *dpp, DBOpParams *params); + int Execute(const DoutPrefixProvider *dpp, DBOpParams *params); + int Bind(const DoutPrefixProvider *dpp, DBOpParams *params); +}; + +class SQLRemoveLCEntry : public SQLiteDB, public RemoveLCEntryOp { + private: + sqlite3 **sdb = NULL; + sqlite3_stmt *stmt = NULL; // Prepared statement + + public: + SQLRemoveLCEntry(void **db, string db_name, CephContext *cct) : SQLiteDB((sqlite3 *)(*db), db_name, cct), sdb((sqlite3 **)db) {} + ~SQLRemoveLCEntry() { + if (stmt) + sqlite3_finalize(stmt); + } + int Prepare(const DoutPrefixProvider *dpp, DBOpParams *params); + int Execute(const DoutPrefixProvider *dpp, DBOpParams *params); + int Bind(const DoutPrefixProvider *dpp, DBOpParams *params); +}; + +class SQLGetLCEntry : public SQLiteDB, public GetLCEntryOp { + private: + sqlite3 **sdb = NULL; + sqlite3_stmt *stmt = NULL; // Prepared statement + sqlite3_stmt *next_stmt = NULL; // Prepared statement + + public: + SQLGetLCEntry(void **db, string db_name, CephContext *cct) : SQLiteDB((sqlite3 *)(*db), db_name, cct), sdb((sqlite3 **)db) {} + ~SQLGetLCEntry() { + if (stmt) + sqlite3_finalize(stmt); + if (next_stmt) + sqlite3_finalize(next_stmt); + } + int Prepare(const DoutPrefixProvider *dpp, DBOpParams *params); + int Execute(const DoutPrefixProvider *dpp, DBOpParams *params); + int Bind(const DoutPrefixProvider *dpp, DBOpParams *params); +}; + +class SQLListLCEntries : public SQLiteDB, public ListLCEntriesOp { + private: + sqlite3 **sdb = NULL; + sqlite3_stmt *stmt = NULL; // Prepared statement + + public: + SQLListLCEntries(void **db, string db_name, CephContext *cct) : SQLiteDB((sqlite3 *)(*db), db_name, cct), sdb((sqlite3 **)db) {} + ~SQLListLCEntries() { + if (stmt) + sqlite3_finalize(stmt); + } + int Prepare(const DoutPrefixProvider *dpp, DBOpParams *params); + int Execute(const DoutPrefixProvider *dpp, DBOpParams *params); + int Bind(const DoutPrefixProvider *dpp, DBOpParams *params); +}; + +class SQLInsertLCHead : public SQLiteDB, public InsertLCHeadOp { + private: + sqlite3 **sdb = NULL; + sqlite3_stmt *stmt = NULL; // Prepared statement + + public: + SQLInsertLCHead(void **db, string db_name, CephContext *cct) : SQLiteDB((sqlite3 *)(*db), db_name, cct), sdb((sqlite3 **)db) {} + ~SQLInsertLCHead() { + if (stmt) + sqlite3_finalize(stmt); + } + int Prepare(const DoutPrefixProvider *dpp, DBOpParams *params); + int Execute(const DoutPrefixProvider *dpp, DBOpParams *params); + int Bind(const DoutPrefixProvider *dpp, DBOpParams *params); +}; + +class SQLRemoveLCHead : public SQLiteDB, public RemoveLCHeadOp { + private: + sqlite3 **sdb = NULL; + sqlite3_stmt *stmt = NULL; // Prepared statement + + public: + SQLRemoveLCHead(void **db, string db_name, CephContext *cct) : SQLiteDB((sqlite3 *)(*db), db_name, cct), sdb((sqlite3 **)db) {} + ~SQLRemoveLCHead() { + if (stmt) + sqlite3_finalize(stmt); + } + int Prepare(const DoutPrefixProvider *dpp, DBOpParams *params); + int Execute(const DoutPrefixProvider *dpp, DBOpParams *params); + int Bind(const DoutPrefixProvider *dpp, DBOpParams *params); +}; + +class SQLGetLCHead : public SQLiteDB, public GetLCHeadOp { + private: + sqlite3 **sdb = NULL; + sqlite3_stmt *stmt = NULL; // Prepared statement + + public: + SQLGetLCHead(void **db, string db_name, CephContext *cct) : SQLiteDB((sqlite3 *)(*db), db_name, cct), sdb((sqlite3 **)db) {} + ~SQLGetLCHead() { + if (stmt) + sqlite3_finalize(stmt); + } + int Prepare(const DoutPrefixProvider *dpp, DBOpParams *params); + int Execute(const DoutPrefixProvider *dpp, DBOpParams *params); + int Bind(const DoutPrefixProvider *dpp, DBOpParams *params); +}; + #endif diff --git a/src/rgw/store/dbstore/tests/dbstore_tests.cc b/src/rgw/store/dbstore/tests/dbstore_tests.cc index 2d02bf24144f..fcdd6a079a6d 100644 --- a/src/rgw/store/dbstore/tests/dbstore_tests.cc +++ b/src/rgw/store/dbstore/tests/dbstore_tests.cc @@ -100,7 +100,6 @@ namespace { GlobalParams.op.obj.state.obj.key.instance = "inst1"; GlobalParams.op.obj_data.part_num = 0; - /* As of now InitializeParams doesnt do anything * special based on fop. Hence its okay to do * global initialization once. @@ -997,6 +996,113 @@ TEST_F(DBStoreTest, DeleteObject) { ASSERT_EQ(ret, 0); } +TEST_F(DBStoreTest, LCTables) { + struct DBOpParams params = GlobalParams; + int ret = -1; + + ret = db->createLCTables(dpp); + ASSERT_GE(ret, 0); +} + +TEST_F(DBStoreTest, LCHead) { + struct DBOpParams params = GlobalParams; + int ret = -1; + std::string index1 = "bucket1"; + std::string index2 = "bucket2"; + time_t lc_time = ceph_clock_now(); + rgw::sal::Lifecycle::LCHead head; + std::string ents[] = {"entry1", "entry2", "entry3"}; + rgw::sal::Lifecycle::LCHead head1 = {lc_time, ents[0]}; + rgw::sal::Lifecycle::LCHead head2 = {lc_time, ents[1]}; + rgw::sal::Lifecycle::LCHead head3 = {lc_time, ents[2]}; + + ret = db->put_head(index1, head1); + ASSERT_EQ(ret, 0); + ret = db->put_head(index2, head2); + ASSERT_EQ(ret, 0); + + ret = db->get_head(index1, head); + ASSERT_EQ(ret, 0); + ASSERT_EQ(head.marker, "entry1"); + + ret = db->get_head(index2, head); + ASSERT_EQ(ret, 0); + ASSERT_EQ(head.marker, "entry2"); + + // update index1 + ret = db->put_head(index1, head3); + ASSERT_EQ(ret, 0); + ret = db->get_head(index1, head); + ASSERT_EQ(ret, 0); + ASSERT_EQ(head.marker, "entry3"); + +} +TEST_F(DBStoreTest, LCEntry) { + struct DBOpParams params = GlobalParams; + int ret = -1; + uint64_t lc_time = ceph_clock_now(); + std::string index1 = "lcindex1"; + std::string index2 = "lcindex2"; + typedef enum {lc_uninitial = 1, lc_complete} status; + std::string ents[] = {"bucket1", "bucket2", "bucket3", "bucket4"}; + rgw::sal::Lifecycle::LCEntry entry; + rgw::sal::Lifecycle::LCEntry entry1 = {ents[0], lc_time, lc_uninitial}; + rgw::sal::Lifecycle::LCEntry entry2 = {ents[1], lc_time, lc_uninitial}; + rgw::sal::Lifecycle::LCEntry entry3 = {ents[2], lc_time, lc_uninitial}; + rgw::sal::Lifecycle::LCEntry entry4 = {ents[3], lc_time, lc_uninitial}; + + vector lc_entries; + + ret = db->set_entry(index1, entry1); + ASSERT_EQ(ret, 0); + ret = db->set_entry(index1, entry2); + ASSERT_EQ(ret, 0); + ret = db->set_entry(index1, entry3); + ASSERT_EQ(ret, 0); + ret = db->set_entry(index2, entry4); + ASSERT_EQ(ret, 0); + + // get entry index1, entry1 + ret = db->get_entry(index1, ents[0], entry); + ASSERT_EQ(ret, 0); + ASSERT_EQ(entry.status, lc_uninitial); + ASSERT_EQ(entry.start_time, lc_time); + + // get next entry index1, entry2 + ret = db->get_next_entry(index1, ents[1], entry); + ASSERT_EQ(ret, 0); + ASSERT_EQ(entry.bucket, ents[2]); + ASSERT_EQ(entry.status, lc_uninitial); + ASSERT_EQ(entry.start_time, lc_time); + + // update entry4 to entry5 + entry4.status = lc_complete; + ret = db->set_entry(index2, entry4); + ASSERT_EQ(ret, 0); + ret = db->get_entry(index2, ents[3], entry); + ASSERT_EQ(ret, 0); + ASSERT_EQ(entry.status, lc_complete); + + // list entries + ret = db->list_entries(index1, "", 5, lc_entries); + ASSERT_EQ(ret, 0); + for (const auto& ent: lc_entries) { + cout << "###################### \n"; + cout << "lc entry.bucket : " << ent.bucket << "\n"; + cout << "lc entry.status : " << ent.status << "\n"; + } + + // remove index1, entry3 + ret = db->rm_entry(index1, entry3); + ASSERT_EQ(ret, 0); + + // get next entry index1, entry2.. should be null + entry = {}; + ret = db->get_next_entry(index1, ents[1], entry); + ASSERT_EQ(ret, 0); + ASSERT_EQ(entry.start_time, 0); +} + TEST_F(DBStoreTest, RemoveBucket) { struct DBOpParams params = GlobalParams; int ret = -1; @@ -1030,14 +1136,6 @@ TEST_F(DBStoreTest, InsertTestIDUser) { ASSERT_EQ(ret, 0); } -TEST_F(DBStoreTest, LCTables) { - struct DBOpParams params = GlobalParams; - int ret = -1; - - ret = db->createLCTables(dpp); - ASSERT_EQ(ret, 0); -} - int main(int argc, char **argv) { int ret = -1;