]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/dbstore: LC APIs definition 43433/head
authorSoumya Koduri <skoduri@redhat.com>
Tue, 19 Oct 2021 17:57:56 +0000 (23:27 +0530)
committerSoumya Koduri <skoduri@redhat.com>
Thu, 11 Nov 2021 08:14:19 +0000 (13:44 +0530)
Implement methods to add & fetch LCEntries in dbstore.

Signed-off-by: Soumya Koduri <skoduri@redhat.com>
src/rgw/rgw_sal_dbstore.cc
src/rgw/store/dbstore/common/dbstore.cc
src/rgw/store/dbstore/common/dbstore.h
src/rgw/store/dbstore/sqlite/sqliteDB.cc
src/rgw/store/dbstore/sqlite/sqliteDB.h
src/rgw/store/dbstore/tests/dbstore_tests.cc

index 424a32816d0cb9e2cdf32a30180943bf7b711991..d48b2a395e737d2b97e4685c790e90bbd52a795d 100644 (file)
@@ -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<LCEntry>& 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)
index c771763ff7f046bc3fe234075b557fb1c4b815c1..1b851fa550cf5c79a8415c67216ffea7632ba97d 100644 (file)
@@ -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<string, class ObjectOp*>::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", &params);
+
+  params.op.lc_entry.index = oid;
+  params.op.lc_entry.entry.bucket = marker;
+
+  params.op.query_str = "get_entry";
+  ret = ProcessOp(dpp, "GetLCEntry", &params);
+
+  if (ret) {
+    ldpp_dout(dpp, 0)<<"In GetLCEntry failed err:(" <<ret<<") " << dendl;
+    goto out;
+  }
+
+  if (!params.op.lc_entry.entry.start_time == 0) { //ensure entry found
+    entry = params.op.lc_entry.entry;
+  }
+
+out:
+  return ret;
+}
+
+int DB::get_next_entry(const std::string& oid, std::string& marker,
+                                  rgw::sal::Lifecycle::LCEntry& entry)
+{
+  int ret = 0;
+  const DoutPrefixProvider *dpp = get_def_dpp();
+
+  DBOpParams params = {};
+  InitializeParams(dpp, "GetLCEntry", &params);
+
+  params.op.lc_entry.index = oid;
+  params.op.lc_entry.entry.bucket = marker;
+
+  params.op.query_str = "get_next_entry";
+  ret = ProcessOp(dpp, "GetLCEntry", &params);
+
+  if (ret) {
+    ldpp_dout(dpp, 0)<<"In GetLCEntry failed err:(" <<ret<<") " << dendl;
+    goto out;
+  }
+
+  if (!params.op.lc_entry.entry.start_time == 0) { //ensure entry found
+    entry = params.op.lc_entry.entry;
+  }
+
+out:
+  return ret;
+}
+
+int DB::set_entry(const std::string& oid, const rgw::sal::Lifecycle::LCEntry& entry)
+{
+  int ret = 0;
+  const DoutPrefixProvider *dpp = get_def_dpp();
+
+  DBOpParams params = {};
+  InitializeParams(dpp, "InsertLCEntry", &params);
+
+  params.op.lc_entry.index = oid;
+  params.op.lc_entry.entry = entry;
+
+  ret = ProcessOp(dpp, "InsertLCEntry", &params);
+
+  if (ret) {
+    ldpp_dout(dpp, 0)<<"In InsertLCEntry failed err:(" <<ret<<") " << dendl;
+    goto out;
+  }
+
+out:
+  return ret;
+}
+
+int DB::list_entries(const std::string& oid, const std::string& marker,
+                                uint32_t max_entries, vector<rgw::sal::Lifecycle::LCEntry>& entries)
+{
+  int ret = 0;
+  const DoutPrefixProvider *dpp = get_def_dpp();
+
+  entries.clear();
+
+  DBOpParams params = {};
+  InitializeParams(dpp, "ListLCEntries", &params);
+
+  params.op.lc_entry.index = oid;
+  params.op.lc_entry.min_marker = marker;
+  params.op.list_max_count = max_entries;
+
+  ret = ProcessOp(dpp, "ListLCEntries", &params);
+
+  if (ret) {
+    ldpp_dout(dpp, 0)<<"In ListLCEntries failed err:(" <<ret<<") " << dendl;
+    goto out;
+  }
+
+  for (auto& entry : params.op.lc_entry.list_entries) {
+    entries.push_back(std::move(entry));
+  }
+
+out:
+  return ret;
+}
+
+int DB::rm_entry(const std::string& oid, const rgw::sal::Lifecycle::LCEntry& entry)
+{
+  int ret = 0;
+  const DoutPrefixProvider *dpp = get_def_dpp();
+
+  DBOpParams params = {};
+  InitializeParams(dpp, "RemoveLCEntry", &params);
+
+  params.op.lc_entry.index = oid;
+  params.op.lc_entry.entry = entry;
+
+  ret = ProcessOp(dpp, "RemoveLCEntry", &params);
+
+  if (ret) {
+    ldpp_dout(dpp, 0)<<"In RemoveLCEntry failed err:(" <<ret<<") " << dendl;
+    goto out;
+  }
+
+out:
+  return ret;
+}
+
+int DB::get_head(const std::string& oid, rgw::sal::Lifecycle::LCHead& head)
+{
+  int ret = 0;
+  const DoutPrefixProvider *dpp = get_def_dpp();
+
+  DBOpParams params = {};
+  InitializeParams(dpp, "GetLCHead", &params);
+
+  params.op.lc_head.index = oid;
+
+  ret = ProcessOp(dpp, "GetLCHead", &params);
+
+  if (ret) {
+    ldpp_dout(dpp, 0)<<"In GetLCHead failed err:(" <<ret<<") " << dendl;
+    goto out;
+  }
+
+  head = params.op.lc_head.head;
+
+out:
+  return ret;
+}
+
+int DB::put_head(const std::string& oid, const rgw::sal::Lifecycle::LCHead& head)
+{
+  int ret = 0;
+  const DoutPrefixProvider *dpp = get_def_dpp();
+
+  DBOpParams params = {};
+  InitializeParams(dpp, "InsertLCHead", &params);
+
+  params.op.lc_head.index = oid;
+  params.op.lc_head.head = head;
+
+  ret = ProcessOp(dpp, "InsertLCHead", &params);
+
+  if (ret) {
+    ldpp_dout(dpp, 0)<<"In InsertLCHead failed err:(" <<ret<<") " << dendl;
+    goto out;
+  }
+
+out:
+  return ret;
+}
+
 } } // namespace rgw::store
 
index 9cf1b4fd669bbb7355698e6b36e8a767417168c5..18aef417cd7ffb44059b98de61630080576daee9 100644 (file)
@@ -98,6 +98,19 @@ struct DBOpObjectDataInfo {
   bufferlist data{};
 };
 
+struct DBOpLCHeadInfo {
+  string index;
+  rgw::sal::Lifecycle::LCHead head;
+};
+
+struct DBOpLCEntryInfo {
+  string index;
+  rgw::sal::Lifecycle::LCEntry entry;
+  // used for list query
+  string min_marker;
+  list<rgw::sal::Lifecycle::LCEntry> 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 &params) {
+      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 &params) {
+      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 &params) {
+      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 &params) {
+      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 &params) {
+      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 &params) {
+      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 &params) {
+      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<rgw::sal::Lifecycle::LCEntry>& 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 {
index 389fd0d5fba1e41a9373e83ec2eb0ab555d3c83b..dc5463f5b09ff9587431811a8a6a9539f6abcb84 100644 (file)
@@ -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;
+}
index 5d747f7a57453222f75c78e942d1ff9608c77078..55e3dc33aa348fee2ce6e1f14a12f6e56e3117d2 100644 (file)
@@ -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
index 2d02bf24144f2e599d6432962523734f91df1842..fcdd6a079a6da90cff8050d8be333c62327a8df5 100644 (file)
@@ -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<rgw::sal::Lifecycle::LCEntry> 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;