Commit b2b7aef5 authored by Giorgio Azzinnaro's avatar Giorgio Azzinnaro

added Marshaller

parent aa0d3577
......@@ -19,6 +19,13 @@
#include "schema.h"
using google::protobuf::Message;
using google::protobuf::Reflection;
using google::protobuf::Descriptor;
using google::protobuf::FieldDescriptor;
using profanedb::protobuf::Key;
profanedb::boot::protobuf::Schema::Schema()
{
}
......@@ -27,7 +34,7 @@ profanedb::boot::protobuf::Schema::~Schema()
{
}
bool profanedb::boot::protobuf::Schema::IsKeyable(const google::protobuf::Message & message) const
bool profanedb::boot::protobuf::Schema::IsKeyable(const Message & message) const
{
const Descriptor * descriptor = message.GetDescriptor();
......@@ -38,7 +45,7 @@ bool profanedb::boot::protobuf::Schema::IsKeyable(const google::protobuf::Messag
return false;
}
profanedb::protobuf::Key profanedb::boot::protobuf::Schema::GetKey(const google::protobuf::Message & message) const
Key profanedb::boot::protobuf::Schema::GetKey(const Message & message) const
{
const Descriptor * descriptor = message.GetDescriptor();
......@@ -52,9 +59,9 @@ profanedb::protobuf::Key profanedb::boot::protobuf::Schema::GetKey(const google:
}
std::vector<const google::protobuf::Message *> profanedb::boot::protobuf::Schema::GetNestedMessages(
const google::protobuf::Message & message) const
const Message & message) const
{
std::vector<const google::protobuf::Message *> nested;
std::vector<const Message *> nested;
const Reflection * reflection = message.GetReflection();
const Descriptor * descriptor = message.GetDescriptor();
......@@ -68,21 +75,21 @@ std::vector<const google::protobuf::Message *> profanedb::boot::protobuf::Schema
return nested;
}
profanedb::protobuf::Key profanedb::boot::protobuf::Schema::FieldToKey(
Key profanedb::boot::protobuf::Schema::FieldToKey(
const Message & message,
const google::protobuf::FieldDescriptor * fd)
const FieldDescriptor * fd)
{
profanedb::protobuf::Key key;
Key key;
*key.mutable_message_type() = message.GetTypeName();
*key.mutable_field() = fd->name();
const google::protobuf::Reflection * reflection = message.GetReflection();
const Reflection * reflection = message.GetReflection();
if (fd->is_repeated()) {
for (int y = 0; y < reflection->FieldSize(message, fd); y++) {
switch (fd->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, METHOD) \
case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
*key.mutable_value() += "$" + std::to_string(reflection->GetRepeated##METHOD(message, fd, y)); \
break;
......@@ -95,13 +102,13 @@ profanedb::protobuf::Key profanedb::boot::protobuf::Schema::FieldToKey(
HANDLE_TYPE(BOOL , Bool );
#undef HANDLE_TYPE
case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
case FieldDescriptor::CPPTYPE_ENUM:
*key.mutable_value() += "$" + std::to_string(reflection->GetRepeatedEnum(message, fd, y)->index());
break;
case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
case FieldDescriptor::CPPTYPE_STRING:
*key.mutable_value() += "$" + reflection->GetRepeatedString(message, fd, y);
break;
case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
case FieldDescriptor::CPPTYPE_MESSAGE:
*key.mutable_value() += "$" + reflection->GetRepeatedMessage(message, fd, y).SerializeAsString();
break;
}
......@@ -109,7 +116,7 @@ profanedb::protobuf::Key profanedb::boot::protobuf::Schema::FieldToKey(
} else {
switch (fd->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, METHOD) \
case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \
case FieldDescriptor::CPPTYPE_##CPPTYPE: \
*key.mutable_value() = std::to_string(reflection->Get##METHOD(message, fd)); \
break;
......@@ -122,13 +129,13 @@ profanedb::protobuf::Key profanedb::boot::protobuf::Schema::FieldToKey(
HANDLE_TYPE(BOOL , Bool );
#undef HANDLE_TYPE
case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
case FieldDescriptor::CPPTYPE_ENUM:
*key.mutable_value() = std::to_string(reflection->GetEnum(message, fd)->index());
break;
case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
case FieldDescriptor::CPPTYPE_STRING:
*key.mutable_value() = reflection->GetString(message, fd);
break;
case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
case FieldDescriptor::CPPTYPE_MESSAGE:
*key.mutable_value() = reflection->GetMessage(message, fd).SerializeAsString();
break;
}
......
......@@ -31,11 +31,6 @@ namespace profanedb {
namespace boot {
namespace protobuf {
using google::protobuf::Message;
using google::protobuf::Reflection;
using google::protobuf::Descriptor;
using google::protobuf::FieldDescriptor;
// Redundant here, might be relevant for other kind of "Message" classes,
// to copy and paste from profanedb::boot::Schema interface
// Can be changed if collisions occur
......@@ -59,7 +54,7 @@ public:
virtual std::vector<const Message *> GetNestedMessages(const Message & message) const override;
private:
static profanedb::protobuf::Key FieldToKey(const Message & message, const FieldDescriptor * fd);
static profanedb::protobuf::Key FieldToKey(const Message & message, const google::protobuf::FieldDescriptor * fd);
};
}
}
......
......@@ -38,7 +38,7 @@ public:
virtual bool IsKeyable(const Message & message) const = 0;
// Extract a Key from a Message
virtual protobuf::Key GetKey(const Message & message) const = 0;
virtual profanedb::protobuf::Key GetKey(const Message & message) const = 0;
// Retrieve nested messages from a message
virtual std::vector<const Message *> GetNestedMessages(const Message & message) const = 0;
......
......@@ -36,13 +36,21 @@ profanedb::Db<Message>::~Db()
template<typename Message>
const Message & profanedb::Db<Message>::Get(const protobuf::Key & key) const
{
this->schema->
this->storage->Retrieve(key);
// Unmarshal message
// For each nested key retrieve and set message
// TODO Storable to Message and return
}
template<typename Message>
bool profanedb::Db<Message>::Put(const Message & message)
{
// TODO Message to Storable
// storage->Store()
}
template<typename Message>
bool profanedb::Db<Message>::Delete(const protobuf::Key & key)
{
}
......@@ -17,6 +17,8 @@
*
*/
#include <memory>
#include <profanedb/boot/schema.h>
#include <profanedb/vault/storage.h>
......
add_library(profanedb_format protobuf/marshaller.cpp)
target_link_libraries(profanedb_format profanedb_protobuf)
/*
* ProfaneDB - A Protocol Buffers database.
* Copyright (C) 2017 "Giorgio Azzinnaro" <giorgio.azzinnaro@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PROFANEDB_FORMAT_MARSHALLER_H
#define PROFANEDB_FORMAT_MARSHALLER_H
#include <profanedb/protobuf/storage.pb.h>
namespace profanedb {
namespace format {
template<typename Message>
class Marshaller
{
public:
virtual ~Marshaller() = 0;
virtual profanedb::protobuf::MessageTreeNode Marshal(const Message & message) = 0;
virtual const Message & Unmarshal(const profanedb::protobuf::StorableMessage & storable) = 0;
};
}
}
#endif // PROFANEDB_FORMAT_MARSHALLER_H
This diff is collapsed.
/*
* <one line to give the program's name and a brief idea of what it does.>
* Copyright (C) 2017 <copyright holder> <email>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PROFANEDB_FORMAT_PROTOBUF_MARSHALLER_H
#define PROFANEDB_FORMAT_PROTOBUF_MARSHALLER_H
#include <google/protobuf/message.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/dynamic_message.h>
#include <profanedb/protobuf/options.pb.h>
#include <profanedb/vault/storage.h>
#include <profanedb/format/marshaller.h>
namespace profanedb {
namespace format {
namespace protobuf {
class Marshaller : profanedb::format::Marshaller<google::protobuf::Message>
{
public:
Marshaller(
google::protobuf::DescriptorPool & schemaPool,
google::protobuf::DescriptorPool & normalizedPool,
const profanedb::vault::Storage & storage
);
~Marshaller();
virtual MessageTreeNode Marshal(const google::protobuf::Message & message) override;
virtual const google::protobuf::Message & Unmarshal(const StorableMessage & storable) override;
private:
// TODO schemaPool, normalizedPool and CopyField are strictly related, should have their class
// schemaPool keeps track of the original messages
google::protobuf::DescriptorPool & schemaPool;
// For each keyable message in schema, there is a normalized version
// which has Key in place of nested keyable messages
google::protobuf::DescriptorPool & normalizedPool;
// Because a StorableMessage only holds references to its children objects,
// Storage is used to recursively retrieve them.
const profanedb::vault::Storage & storage;
google::protobuf::DynamicMessageFactory messageFactory;
// Copy a field from a message to another.
// Differs from MergeFrom because it doesn't check whether Descriptors match.
void CopyField(
const google::protobuf::FieldDescriptor * fromField,
const google::protobuf::Message & from,
google::protobuf::Message * to);
// Convert a field from a message to a Key object
profanedb::protobuf::Key FieldToKey(
const google::protobuf::Message & message,
const google::protobuf::FieldDescriptor * fd);
};
}
}
}
#endif // PROFANEDB_FORMAT_PROTOBUF_MARSHALLER_H
......@@ -64,7 +64,7 @@ grpc::Status profanedb::server::Server::DbServiceImpl::Get(grpc::ServerContext *
grpc::Status profanedb::server::Server::DbServiceImpl::Put(grpc::ServerContext * context, const profanedb::protobuf::PutReq * request, profanedb::protobuf::PutResp * response)
{
// TODO Unpack
this->profanedb.Put(request->serializable());
// this->profanedb.Put(request->serializable());
return grpc::Status::OK;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment