| #include "SQLiteWrapper.h" | |
| #include <google/protobuf/message.h> | |
| // This alias template is used below to define a serialization hook and | |
| // a deserialization hook for `google::protobuf::Message`s. | |
| template <typename T> | |
| using is_a_protobuf_message | |
| = std::enable_if_t<std::is_base_of_v<google::protobuf::Message, T>>; | |
| // Serialize a `google::protobuf::Message` into a `sqlite::blob` by invoking the | |
| // `SerializeAsString` instance method. Internally, `sqlite::blob` corresponds | |
| // to SQLite's BLOB data type. | |
| template <typename T> | |
| constexpr auto sqlite::user_serialize_fn<T, is_a_protobuf_message<T>> = | |
| [] (const google::protobuf::Message &message) -> sqlite::blob { | |
| return sqlite::blob{message.SerializeAsString()}; | |
| }; | |
| // Deserialize a `sqlite::blob` into a `google::protobuf::Message` by parsing | |
| // the underlying bytes of the `sqlite::blob`. | |
| template <typename T> | |
| constexpr auto sqlite::user_deserialize_fn<T, is_a_protobuf_message<T>> = | |
| [] (sqlite::blob_view serialized_message) -> T { | |
| T message; | |
| message.ParseFromArray(&serialized_message[0], | |
| serialized_message.length()); | |
| return message; | |
| }; | |
| static const char db_name[] = "my_database.db"; | |
| using db = sqlite::Database<db_name>; | |
| void example(const std::string &name, | |
| const google::protobuf::Message &new_message) { | |
| static const char insert_query[] | |
| = R"(insert into my_table (my_name, my_column) values (?1, ?2))"; | |
| // We can now bind `google::protobuf::Message`s natively. The wrapper will use the | |
| // serialization and deserialization hooks to convert the messages to and from a native | |
| // SQLite data type. | |
| db::query<insert_query>(name, new_message); | |
| } |