diff --git a/changelog/1.2.0.md b/changelog/1.2.0.md index e69de29b..c31a9802 100644 --- a/changelog/1.2.0.md +++ b/changelog/1.2.0.md @@ -0,0 +1,169 @@ +# Oat++ 1.2.0 + +Feel free to ask questions - [Chat on Gitter](https://gitter.im/oatpp-framework/Lobby) + +Contents: + +- [Continuous Multipart Streaming](#continuous-multipart-streaming) +- [Changes In ConnectionProvider Interface](#changes-in-connectionprovider-interface) +- [Object-Mapping - Type Interpretations](#type-interpretations) +- [The new Oat++ ORM](#orm) + +## Continuous Multipart Streaming + +Now it's possible to continuously stream multipart data to the client. +For example, you can implement `multipart/x-mixed-replace` video stream. + +Both Simple-APIs and Async-APIs available. + +```cpp +using namespace oatpp::web::mime::multipart; + +class MPStream : public Multipart { +public: + + MPStream() + : Multipart(generateRandomBoundary()) + {} + + std::shared_ptr readNextPart(async::Action& action /* For Simple-API action is ignored */) override { + + std::this_thread::sleep_for(std::chrono::seconds(1)); // For Simple-API you may sleep just like that + + oatpp::String frameData = "" // frame data. One jpeg image. + + auto part = std::make_shared(); + part->putHeader(Header::CONTENT_TYPE, "image/jpeg"); + part->setDataInfo(std::make_shared(frameData)); + + return part; + + } + + void writeNextPart(const std::shared_ptr& part, async::Action& action) override { + throw std::runtime_error("No writes here!!!"); + } + +}; + +ENDPOINT("GET", "multipart-stream", multipartStream) { + auto multipart = std::make_shared(); + auto body = std::make_shared( + multipart, + "multipart/x-mixed-replace", + true /* flush parts */ + ); + return OutgoingResponse::createShared(Status::CODE_200, body); +} +``` + +## Changes In ConnectionProvider Interface + +Both `oatpp::network::ServerConnectionProvider` and `oatpp::network::ClientConnectionProvider` +are now subclasses of a general `oatpp::provider::Provider` class. + +Renamed methods: + +- `getConnection()` --> `get()` +- `getConnectionAsync()` --> `getAsync()` +- `invalidateConnection()` --> `invalidate()` + +This was done to unify providers' APIs and to have same API for all resource providers and resource pools. +Connection Providers and Connection Pools of the new ORM database adaptors are implemented based on the same functionality. + +## Type Interpretations + +To simplify the integration of custom types with oatpp Object-Mapping framework the the "Type Interpretation" feature was introduced. + +Let's say you have some struct that is not part of oatpp object-mapping framework. + +```cpp +struct VPoint { + v_int32 x; + v_int32 y; + v_int32 z; +}; +``` + +To integrate it with oatpp object-mapping you can do the following: + +```cpp +namespace __class { + class PointClass; +} + +/* Declare ObjectWrapper for your type */ +/* Mapping-Enabled Point */ +typedef oatpp::data::mapping::type::Primitive Point; + +namespace __class { + + /** + * Type info + */ + class PointClass { + private: + + /** + * Type interpretation + */ + class Inter : public oatpp::Type::Interpretation> { + public: + + oatpp::UnorderedFields interpret(const Point& value) const override { + return {{"x", value->x}, {"y", value->y}, {"z", value->z}}; + } + + Point reproduce(const oatpp::UnorderedFields map) const override { + return Point({map["x"], map["y"], map["z"]}); + } + + }; + + public: + + static const oatpp::ClassId CLASS_ID; + + static oatpp::Type* getType(){ + static Type type( + CLASS_ID, nullptr, nullptr, nullptr, nullptr, + { + {"my-types", new Inter()} //<-- Add type interpretation + } + ); + return &type; + } + + }; + + const oatpp::ClassId PointClass::CLASS_ID("my-types::Point"); + +} +``` + +Now the "Point" struct can be serialized/deserialized with object mappers. + +```cpp +oatpp::parser::json::mapping::ObjectMapper mapper; + +{ + auto config = mapper.getSerializer()->getConfig(); + config->enableInterpretations = {"my-types"}; // Enable "my-types" for serializer +} + +{ + auto config = mapper.getDeserializer()->getConfig(); + config->enableInterpretations = {"my-types"}; // Enable "my-types" for deserializer +} + +Point point ({1, 2, 3}); // Create mapping-enabled Point + +auto json = mapper.writeToString(point); // Serialize Point +auto pointClone = mapper.readFromString(json); // Deserialize Point +``` + +## ORM + +The main feature of the `1.2.0` release is the new ORM Framework. +For details see - [Object-Relational Mapping (ORM) framework](https://oatpp.io/docs/components/orm/) +