# 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.
