forked from aquarist-labs/ceph
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request aquarist-labs#150 from 0xavi0/480-db-schema-change
rgw/sfs: change db schema as described in ADR.
- Loading branch information
Showing
25 changed files
with
1,489 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,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" | ||
|
||
/// 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::system_error( | ||
ERANGE, std::system_category(), | ||
"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::system_error( | ||
ERANGE, std::system_category(), | ||
"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::system_error(ERANGE, std::system_category(), 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::system_error(ERANGE, std::system_category(), 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,71 @@ | ||
// -*- 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::system_error( | ||
ERANGE, std::system_category(), | ||
"incorrect uuid string (" + std::string(row_value) + ")" | ||
); | ||
} | ||
return ret_value; | ||
} else { | ||
// ! row_value | ||
throw std::system_error( | ||
ERANGE, std::system_category(), "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.