This repository has been archived by the owner on Jan 3, 2024. It is now read-only.
forked from ceph/ceph
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rgw/sfs: change db schema as described in ADR.
Changes the db schema following [this ADR](https://github.com/aquarist-labs/s3gw/pull/497). It also deletes repeated fields that we had in objects vs versioned_objects tables. Logic of `sfs` was intentionally not updated in this PR. (For example new field `version_type` is added to the schema, but still not used). Updates in logic, specially in versioning logic, will come in a future PR. New Features: **Sqliteorm type bindings for the following types.** * `uuid_d` * `ceph::real_time` * `rgw::sal::sfs::ObjetState` * `rgw::sal::sfs::VersionType` In general, any enum type that has a `LAST_VALUE` item assigned to the last valid value and that also starts with 0 is eligible to be binded to sqliteorm, as the type binding for enums is generic. For example: you can create an enum like: ```c++ enum class TestEnum { WHATEVER = 0, SOMETHING_ELSE, AND_THIS, LAST_VALUE = AND_THIS }; ``` and use it right away in sqliteorm. **Object has no explicit conversion code** As all the types in the `object` are compatible with `sqliteorm` we don't need extra conversion layer. This is a preview of what we can do with the rest of database objects once `BLOBS` are also type binded in the future. That was not done in this PR to avoid too many changes. Note: The new type `VersionType` was added as a new file `version_type.h` because we are in a re-design process and I wasn't sure if it should be located in any other existing file that might be eligible to be deleted in the near future. Fixes: https://github.com/aquarist-labs/s3gw/issues/480 Signed-off-by: Xavi Garcia <xavi.garcia@suse.com>
- Loading branch information
Showing
25 changed files
with
1,483 additions
and
975 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t | ||
// vim: ts=8 sw=2 smarttab ft=cpp | ||
/* | ||
* Ceph - scalable distributed file system | ||
* SFS SAL implementation | ||
* | ||
* Copyright (C) 2023 SUSE LLC | ||
* | ||
* This is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License version 2.1, as published by the Free Software | ||
* Foundation. See file COPYING. | ||
*/ | ||
#pragma once | ||
|
||
#include <type_traits> | ||
|
||
#include "rgw/driver/sfs/sqlite/sqlite_orm.h" | ||
|
||
/// sqliteorm binding for enum types. | ||
/// This binding can be used for any enum that has the LAST_VALUE value set to | ||
/// the last possible value and the initial value set to 0. | ||
/// This is used for the conversion from uint to enum to ensure that the uint | ||
/// value is not out of range. | ||
namespace sqlite_orm { | ||
template <class T> | ||
struct type_printer<T, typename std::enable_if<std::is_enum_v<T>>::type> | ||
: public integer_printer {}; | ||
|
||
template <class T> | ||
struct statement_binder<T, typename std::enable_if<std::is_enum_v<T>>::type> { | ||
int bind(sqlite3_stmt* stmt, int index, const T& value) const { | ||
return statement_binder<uint>().bind(stmt, index, static_cast<uint>(value)); | ||
} | ||
}; | ||
|
||
template <class T> | ||
struct field_printer<T, typename std::enable_if<std::is_enum_v<T>>::type> { | ||
std::string operator()(const T& value) const { | ||
return std::to_string(static_cast<uint>(value)); | ||
} | ||
}; | ||
|
||
template <class T> | ||
struct row_extractor<T, typename std::enable_if<std::is_enum_v<T>>::type> { | ||
T extract(uint row_value) const { | ||
if (row_value > static_cast<uint>(T::LAST_VALUE)) { | ||
throw(std::runtime_error( | ||
"Invalid enum value found: (" + std::to_string(row_value) + ")" | ||
)); | ||
} | ||
return static_cast<T>(row_value); | ||
} | ||
|
||
T extract(sqlite3_stmt* stmt, int columnIndex) const { | ||
auto int_value = sqlite3_column_int(stmt, columnIndex); | ||
if (int_value < 0) { | ||
throw(std::runtime_error( | ||
"Invalid enum value found: (" + std::to_string(int_value) + ")" | ||
)); | ||
} | ||
return this->extract(static_cast<uint>(int_value)); | ||
} | ||
}; | ||
|
||
} // namespace sqlite_orm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t | ||
// vim: ts=8 sw=2 smarttab ft=cpp | ||
/* | ||
* Ceph - scalable distributed file system | ||
* SFS SAL implementation | ||
* | ||
* Copyright (C) 2023 SUSE LLC | ||
* | ||
* This is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License version 2.1, as published by the Free Software | ||
* Foundation. See file COPYING. | ||
*/ | ||
#pragma once | ||
|
||
#include "common/ceph_time.h" | ||
#include "rgw/driver/sfs/sqlite/sqlite_orm.h" | ||
|
||
/// ceph::real_time is represented as a uint64 (unsigned). | ||
/// SQLite works with int64 (signed) values, which means we lose 1 bit of | ||
/// resolution. | ||
/// This means max possible time to be stored is 2262-04-11 23:47:16.854775807 | ||
/// timestamps are stored with the same resolution as | ||
/// ceph::real_cock::time_point (nanoseconds) | ||
namespace rgw::sal::sfs::sqlite { | ||
|
||
static int64_t time_point_to_int64(const ceph::real_time& t) { | ||
uint64_t nanos = | ||
std::chrono::duration_cast<std::chrono::nanoseconds>(t.time_since_epoch()) | ||
.count(); | ||
// we check that the value is not greater than int64 max | ||
if (nanos > std::numeric_limits<int64_t>::max()) { | ||
std::stringstream oss; | ||
oss << "Error converting ceph::real_time to int64. " | ||
"Nanoseconds value: " | ||
<< nanos << " is out of range"; | ||
throw std::runtime_error(oss.str()); | ||
} | ||
// we can safely static_cast to int64_t now | ||
return static_cast<int64_t>(nanos); | ||
} | ||
|
||
static ceph::real_time time_point_from_int64(int64_t value) { | ||
std::optional<ceph::real_time> ret; | ||
if (value < 0) { | ||
// to ensure that we stick to the int64 positive range. | ||
std::stringstream oss; | ||
oss << "Error converting int64 nanoseconds value to " | ||
"ceph::real_cock::time_point. Value: " | ||
<< value << " is out of range"; | ||
throw std::runtime_error(oss.str()); | ||
} | ||
uint64_t uint64_nanos = static_cast<uint64_t>(value); | ||
return ceph::real_time(std::chrono::nanoseconds(uint64_nanos)); | ||
} | ||
|
||
} // namespace rgw::sal::sfs::sqlite | ||
|
||
namespace sqlite_orm { | ||
|
||
template <> | ||
struct type_printer<ceph::real_time> : public integer_printer {}; | ||
|
||
template <> | ||
struct statement_binder<ceph::real_time> { | ||
int bind(sqlite3_stmt* stmt, int index, const ceph::real_time& value) const { | ||
return statement_binder<uint64_t>().bind( | ||
stmt, index, rgw::sal::sfs::sqlite::time_point_to_int64(value) | ||
); | ||
} | ||
}; | ||
|
||
template <> | ||
struct field_printer<ceph::real_time> { | ||
std::string operator()(const ceph::real_time& t) const { | ||
auto int_value = rgw::sal::sfs::sqlite::time_point_to_int64(t); | ||
return std::to_string(int_value); | ||
} | ||
}; | ||
|
||
template <> | ||
struct row_extractor<ceph::real_time> { | ||
ceph::real_time extract(int64_t row_value) const { | ||
return rgw::sal::sfs::sqlite::time_point_from_int64(row_value); | ||
} | ||
|
||
ceph::real_time extract(sqlite3_stmt* stmt, int columnIndex) const { | ||
auto int_value = sqlite3_column_int64(stmt, columnIndex); | ||
return this->extract(int_value); | ||
} | ||
}; | ||
|
||
} // namespace sqlite_orm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t | ||
// vim: ts=8 sw=2 smarttab ft=cpp | ||
/* | ||
* Ceph - scalable distributed file system | ||
* SFS SAL implementation | ||
* | ||
* Copyright (C) 2023 SUSE LLC | ||
* | ||
* This is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License version 2.1, as published by the Free Software | ||
* Foundation. See file COPYING. | ||
*/ | ||
#pragma once | ||
|
||
#include <type_traits> | ||
|
||
#include "rgw/driver/sfs/sqlite/sqlite_orm.h" | ||
#include "rgw_common.h" | ||
|
||
namespace sqlite_orm { | ||
template <> | ||
struct type_printer<uuid_d> : public text_printer {}; | ||
|
||
template <> | ||
struct statement_binder<uuid_d> { | ||
int bind(sqlite3_stmt* stmt, int index, const uuid_d& value) const { | ||
return statement_binder<std::string>().bind(stmt, index, value.to_string()); | ||
} | ||
}; | ||
|
||
template <> | ||
struct field_printer<uuid_d> { | ||
std::string operator()(const uuid_d& value) const { | ||
return value.to_string(); | ||
} | ||
}; | ||
|
||
template <> | ||
struct row_extractor<uuid_d> { | ||
uuid_d extract(const char* row_value) const { | ||
if (row_value) { | ||
uuid_d ret_value; | ||
if (!ret_value.parse(row_value)) { | ||
throw std::runtime_error( | ||
"incorrect uuid string (" + std::string(row_value) + ")" | ||
); | ||
} | ||
return ret_value; | ||
} else { | ||
// ! row_value | ||
throw std::runtime_error("incorrect uuid string (nullptr)"); | ||
} | ||
} | ||
|
||
uuid_d extract(sqlite3_stmt* stmt, int columnIndex) const { | ||
auto str = sqlite3_column_text(stmt, columnIndex); | ||
// sqlite3_colume_text returns const unsigned char* | ||
return this->extract(reinterpret_cast<const char*>(str)); | ||
} | ||
uuid_d extract(sqlite3_value* row_value) const { | ||
// sqlite3_colume_text returns const unsigned char* | ||
auto characters = | ||
reinterpret_cast<const char*>(sqlite3_value_text(row_value)); | ||
return extract(characters); | ||
} | ||
}; | ||
} // namespace sqlite_orm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.