Coder Social home page Coder Social logo

oatpp / oatpp-mongo Goto Github PK

View Code? Open in Web Editor NEW
6.0 3.0 3.0 132 KB

Oat++ native BSON + MongoDB driver implementation based on Oat++ object-mapping sub-framework.

Home Page: https://oatpp.io/

License: Apache License 2.0

CMake 5.87% C++ 93.56% Shell 0.58%
oatpp mongodb bson object-mapping cpp

oatpp-mongo's Introduction

oatpp-mongo Build Status


NOTE:

  • BSON ObjectMapper - ready-to-use.
  • Database driver - in development. While you can do basic CRUD operations, it's still on POC stage. API is not ready and it's not recommended to use. To work with MongoDB - use BSON ObjectMapper + mongocxx driver.

oatpp-mongo is the oatpp native client for MongoDB. It contains DTO to BSON mapper plus database driver.

Find the complete example project using oatpp-mongo here

More about Oat++:

How To Build

oatpp-mongo has no extrernal dependencies (The main oatpp module is still required).
libmongoxcc is used (and linked) in module tests only. Use -DOATPP_BUILD_TESTS=OFF option to build without tests and without dependency on libmongoxcc.

Install oatpp-mongo

  • Clone this repository.

  • In the root of the repository run:

    mkdir build && cd build
    cmake -DOATPP_BUILD_TESTS=OFF ..
    make install

API

Temporary API (using libmongoxcc)

Since oatpp driver is not ready yet, you can use libmongoxcc together with oatpp BSON.

Why using oatpp BSON? - because it's based on oatpp object-mapping framework and it's extremely easy to use.

Create bsonxx::document From Any oatpp Object

/**
 * This is the utility function that you'll need while working libmongoxcc
 */
bsoncxx::document::value Database::createMongoDocument(const oatpp::Void &polymorph) {
  // if you have huge docs, you may want to increase starting BufferOutputStream size.
  // Or you may want to use oatpp::data::stream::ChunkedBuffer instead - for no-copy growth.
  oatpp::data::stream::BufferOutputStream stream;
  
  m_objectMapper.write(&stream, polymorph); //< Serialize oatpp object to BSON.
  
  bsoncxx::document::view view(stream.getData(), stream.getCurrentPosition());
  return bsoncxx::document::value(view);
}

Where m_objectMapper - is oatpp::mongo::bson::mapping::ObjectMapper.

Insert Document

Let's say you have such DTO defined:

class User : public oatpp::DTO {

  DTO_INIT(User, DTO)

  DTO_FIELD(String, _id);
  DTO_FIELD(String, username);
  DTO_FIELD(Boolean, active);
  DTO_FIELD(String, role);

};

Then you can insert your DTO in the database like this:

collection.insert_one(createMongoDocument(myDto));

You can also insert an arbitrary document using oatpp::Any

collection.insert_one(createMongoDocument(
  oatpp::Fields<oatpp::Any>({

    {"username", oatpp::String("Mr. Porridge")},
    {"role", oatpp::String("Admin")},
    {"jacket-color", oatpp::List<oatpp::String>({"red", "green", "blue"})}

  })
));

Read Document

Let's say we have the same DTO - User:

  auto result =
    collection.find_one(createMongoDocument( // <-- Filter
      oatpp::Fields<oatpp::String>({
        {"_id", oatpp::String("<id-to-find>")}
      })
    ));

  if(result) {
    auto view = result->view();
    auto bson = oatpp::String((const char*)view.data(), view.length(), false /* to not copy view data */);
    auto user = m_objectMapper.readFromString<oatpp::Object<User>>(bson);
    // TODO - do somthing with user:)
    // You can then serialize it to JSON using oatpp::parser::json::mapping::ObjectMapper
  }

Examples

oatpp-mongo's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

oatpp-mongo's Issues

collection.find_one query by ObjectId

How can I query by "_id" : ObjectId?. For example:

auto result =
    collection.find_one(createMongoDocument( // <-- Filter
      oatpp::Fields<oatpp::String>({
        {"_id", "ObjectID(\"5f3258cfbaaccedaa5dd2d96\")"}
      })
    ));

How do I define a DTO field as int64 and mapped to MongoDB DateTime?

I'm having difficulty finding an example to define a DTO field and map it to MongoDB as DateTime. The example in this repo doesn't have such field.

With a uint64, it's mapped a timestamp which is not quite what I want. I'm getting compiler error if I do the following complaining "DateTime" is not a defined type.

class MyGroup : public oatpp::DTO {
    DTO_INIT(FingerprintGroup, DTO)

    DTO_FIELD(String, _id);

    DTO_FIELD(String, fpGroupName);
    DTO_FIELD(String, status);
    DTO_FIELD(String, type);
    DTO_FIELD(Int32, version) = 0;
    DTO_FIELD(DateTime, created) = 0L;
    DTO_FIELD(DateTime, updated) = 0L;
};

API question

In file: oatpp-mongo/bson/Types.hpp

Question

Hi there, we are using BODY_DTO(oatpp::Any, value) to capture raw json into our endpoints but having issues with quotes around JSON. We would like to use our own json formats and objects (not DTOs). Therefor we need to be able to retrieve raw json without being encapsulated in quotes. Is there a way to receive JSON in the body and push it into a string or another object type without wrapping the whole JSON object is quotes. For example we want to send: {"user":"admin"} instead of "{"user":"admin"}".

[TODO] add ObjectId constructor from String

Until this implemented users can use the following method:

#include "oatpp-mongo/bson/Types.hpp"
#include "oatpp/encoding/Hex.hpp"
#include "oatpp/core/data/stream/BufferStream.hpp"

oatpp::mongo::bson::ObjectId objectIdFromString(const oatpp::String& hexText) {
  oatpp::data::stream::BufferOutputStream stream(12);
  oatpp::encoding::Hex::decode(&stream, hexText->getData(), hexText->getSize(), false);
  if(stream.getCurrentPosition() != 12) {
    throw std::runtime_error("Error. Invalid string.");
  }
  return oatpp::mongo::bson::ObjectId(stream.getData());
}

auto objId = objectIdFromString("5f9b6ecb21a7da049662e7d2");
OATPP_LOGD("AAA", "objId='%s'", objId->toString()->c_str());

Object mapper gives error when deserializing Int64

This problem is relatively easy to reproduce. When Object Mapper (default) is trying to decode a serialized string (JSON) of an object containing a field that is a list of Int64 and when one of the number's absolute value is small (-103 in this case). The object mapper would throw exception:

2023-07-08 00:06:29 ERROR localhost 494264 DLPFP 0: UploadController.cpp:00678 trid=342343234 rqid=0 tenantid=2400 user='' Decoding error for: { "simhash" : [ -1374461674807444439, -103, 1803150389721624332, -292347449805 ]}, err: [oatpp::mongo::bson::Utils::readPrimitive()]: Error. Can't deserialize Int64 value. BSON document value type is expected to be Int64.

Sample string:
{ "simhash" : [ -1374461674807444439, -103, 1803150389721624332, -292347449805 ]}"

The condition I found for this error is that the int64 absolute value is small. In the test code, it works for testString2 where I changed the small value to a big one. Looks like when the value is between [-2147483648, 2147483648) ie. 2^31, the deserializer will give this error.

Code snippets:

class TestDto : public oatpp::DTO {
    DTO_INIT(TestDto, DTO)

    DTO_FIELD(List<Int64>, simhash);
};

oatpp::Object<TestDto> decodeTestDto(const std::string &line)
{
    auto doc = bsoncxx::from_json(line);
    auto view = doc.view();
    auto bson = oatpp::String((const char *)view.data(), view.length());
    return m_objectMapper.readFromString<oatpp::Object<TestDto>>(bson);
}

Testing Code and sample string:

std::string testString = "{ \"simhash\" : [ -1374461674807444439, -103, 1803150389721624332, -292347449805 ]}";
// the following string works
// std::string testString2 = "{ \"simhash\" : [ -1374461674807444439, -103446167480744443, 1803150389721624332, -292347449805 ]}";
try {
    oatpp::Object<TestDto> testDto = m_allFpGenerator->decodeTestDto(testString);
    LOG(INFO) << "TestDto decode OK for " << testString;
} catch (const std::exception &exc) {
    LOG(ERROR) << "Decoding error for: " << testString << ", err: " << exc.what(); 
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.