mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2024-12-22 22:16:37 +08:00
235 lines
7.3 KiB
Markdown
235 lines
7.3 KiB
Markdown
# 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)
|
|
- [Changes in oatpp::network Namespace](#changes-in-oatppnetwork-namespace)
|
|
- [New Modules](#new-modules)
|
|
|
|
## 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<Part> 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-binary-jpeg-data>" // frame data. One jpeg image.
|
|
|
|
auto part = std::make_shared<Part>();
|
|
part->putHeader(Header::CONTENT_TYPE, "image/jpeg");
|
|
part->setDataInfo(std::make_shared<oatpp::data::stream::BufferInputStream>(frameData));
|
|
|
|
return part;
|
|
|
|
}
|
|
|
|
void writeNextPart(const std::shared_ptr<Part>& part, async::Action& action) override {
|
|
throw std::runtime_error("No writes here!!!");
|
|
}
|
|
|
|
};
|
|
|
|
ENDPOINT("GET", "multipart-stream", multipartStream) {
|
|
auto multipart = std::make_shared<MPStream>();
|
|
auto body = std::make_shared<oatpp::web::protocol::http::outgoing::MultipartBody>(
|
|
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<data::stream::IOStream>` 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.
|
|
|
|
More info on ConnectionProvider changes see here - [Changes in oatpp::network Namespace](#changes-in-oatppnetwork-namespace).
|
|
|
|
## 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<VPoint, __class::PointClass> Point;
|
|
|
|
namespace __class {
|
|
|
|
/**
|
|
* Type info
|
|
*/
|
|
class PointClass {
|
|
private:
|
|
|
|
/**
|
|
* Type interpretation
|
|
*/
|
|
class Inter : public oatpp::Type::Interpretation<Point, oatpp::UnorderedFields<oatpp::Int32>> {
|
|
public:
|
|
|
|
oatpp::UnorderedFields<oatpp::Int32> interpret(const Point& value) const override {
|
|
return {{"x", value->x}, {"y", value->y}, {"z", value->z}};
|
|
}
|
|
|
|
Point reproduce(const oatpp::UnorderedFields<oatpp::Int32> 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,
|
|
{
|
|
{"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->enabledInterpretations = {"my-types"}; // Enable "my-types" for serializer
|
|
}
|
|
|
|
{
|
|
auto config = mapper.getDeserializer()->getConfig();
|
|
config->enabledInterpretations = {"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<Point>(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/)
|
|
|
|
### ORM Adaptors
|
|
|
|
- [oatpp-sqlite](https://github.com/oatpp/oatpp-sqlite) - SQLite adapter for Oat++ ORM. Full support.
|
|
- [oatpp-postgresql](https://github.com/oatpp/oatpp-postgresql) - Oat++ ORM adapter for PostgreSQL. Alpha version.
|
|
|
|
## Changes in oatpp::network Namespace
|
|
|
|
### Moved and Renamed
|
|
|
|
- `oatpp::network::server::SimpleTCPConnectionProvider` --> `oatpp::network::tcp::server::ConnectionProvider`
|
|
- `oatpp::network::client::SimpleTCPConnectionProvider` --> `oatpp::network::tcp::client::ConnectionProvider`
|
|
- `oatpp::network::server::ConnectionHandler` --> `atpp::network::ConnectionHandler`
|
|
- `oatpp::network::server::Server` --> `oatpp::network::Server`
|
|
- `oatpp::network::Connection` --> `oatpp::network::tcp::Connection`
|
|
|
|
### New Classes
|
|
|
|
- `oatpp::network::Address`
|
|
|
|
### New Constructors for Connection Providers
|
|
|
|
oatpp::network::tcp::server::ConnectionProvider
|
|
|
|
```cpp
|
|
oatpp::network::tcp::server::ConnectionProvider::createShared(
|
|
{"localhost", 8000} /* network::Address */
|
|
);
|
|
|
|
oatpp::network::tcp::server::ConnectionProvider::createShared(
|
|
{"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */
|
|
);
|
|
|
|
oatpp::network::tcp::server::ConnectionProvider::createShared(
|
|
{"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */,
|
|
true /* use extended connections */
|
|
);
|
|
```
|
|
|
|
oatpp::network::tcp::client::ConnectionProvider
|
|
|
|
```cpp
|
|
oatpp::network::tcp::client::ConnectionProvider::createShared(
|
|
{"localhost", 8000} /* network::Address */
|
|
);
|
|
|
|
oatpp::network::tcp::client::ConnectionProvider::createShared(
|
|
{"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */
|
|
);
|
|
|
|
oatpp::network::tcp::client::ConnectionProvider::createShared(
|
|
{"localhost", 8000, oatpp::network::Address::IP_4} /* network::Address */,
|
|
true /* use extended connections */
|
|
);
|
|
```
|
|
|
|
## New Modules
|
|
|
|
- [oatpp-sqlite](https://github.com/oatpp/oatpp-sqlite) - SQLite adapter for Oat++ ORM. Full support.
|
|
- [oatpp-postgresql](https://github.com/oatpp/oatpp-postgresql) - Oat++ ORM adapter for PostgreSQL. Alpha version.
|
|
- [oatpp-protobuf](https://github.com/oatpp/oatpp-protobuf) - Protobuf integration with oatpp object-mapping framework. Use
|
|
protobuf objects as regular oatpp DTOs. Serialize/Deserialize protobuf object to/from JSON, BSON and other oatpp supported formats.
|