2022-08-04 19:19:04 +00:00
|
|
|
#include "ExternalDictionaryLibraryBridgeHelper.h"
|
2021-03-05 09:38:00 +00:00
|
|
|
|
2021-10-15 20:18:20 +00:00
|
|
|
#include <Formats/formatBlock.h>
|
2021-03-10 13:10:05 +00:00
|
|
|
#include <Dictionaries/DictionarySourceHelpers.h>
|
2021-10-16 14:03:50 +00:00
|
|
|
#include <QueryPipeline/Pipe.h>
|
2021-08-05 18:08:52 +00:00
|
|
|
#include <Processors/Formats/IInputFormat.h>
|
2021-03-10 13:10:05 +00:00
|
|
|
#include <IO/WriteBufferFromOStream.h>
|
2021-04-02 15:45:42 +00:00
|
|
|
#include <IO/WriteBufferFromString.h>
|
2021-08-01 09:56:48 +00:00
|
|
|
#include <IO/ReadHelpers.h>
|
|
|
|
#include <IO/WriteHelpers.h>
|
2021-03-05 09:38:00 +00:00
|
|
|
#include <Formats/FormatFactory.h>
|
|
|
|
#include <Poco/Util/AbstractConfiguration.h>
|
|
|
|
#include <Common/ShellCommand.h>
|
2022-04-27 15:05:45 +00:00
|
|
|
#include <Common/logger_useful.h>
|
2021-10-02 07:13:14 +00:00
|
|
|
#include <base/range.h>
|
2021-03-22 14:39:17 +00:00
|
|
|
#include <Core/Field.h>
|
2021-03-26 07:05:25 +00:00
|
|
|
#include <Common/escapeForFileName.h>
|
2021-03-05 09:38:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2021-08-01 09:56:48 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int EXTERNAL_LIBRARY_ERROR;
|
|
|
|
extern const int LOGICAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
ExternalDictionaryLibraryBridgeHelper::ExternalDictionaryLibraryBridgeHelper(
|
2021-06-01 12:20:52 +00:00
|
|
|
ContextPtr context_,
|
2021-03-24 08:41:42 +00:00
|
|
|
const Block & sample_block_,
|
2021-07-30 14:20:57 +00:00
|
|
|
const Field & dictionary_id_,
|
|
|
|
const LibraryInitData & library_data_)
|
2022-08-08 14:04:41 +00:00
|
|
|
: LibraryBridgeHelper(context_->getGlobalContext())
|
2021-03-24 08:41:42 +00:00
|
|
|
, sample_block(sample_block_)
|
2021-07-30 14:20:57 +00:00
|
|
|
, library_data(library_data_)
|
2021-03-05 09:38:00 +00:00
|
|
|
, dictionary_id(dictionary_id_)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
Poco::URI ExternalDictionaryLibraryBridgeHelper::getPingURI() const
|
Prepare server-side BridgeHelper for catboost integration
Wall of text, sorry, but I also had to document some stuff for myself:
There are three ways to communicate data using HTTP:
- the HTTP verb: for our purposes, PUT and GET,
- the HTTP path: '/ping', '/request' etc.,
- the HTTP URL parameter(s), e.g. 'method=libNew&dictionary_id=1234'
The bridge will use different handlers for communication with the
external dictionary library and for communication with the catboost
library. Handlers are created based on a combination of the HTTP verb
and the HTTP method. More specifically, there will be combinations
- GET + '/extdict_ping'
- PUT + '/extdict_request'
- GET + '/catboost_ping'
- PUT + '/catboost_request'.
For each combination, the bridge expects a certain set of URL
parameters, e.g. for the first combination parameter "dictionary_id" is
expected.
Starting with this commit, the library-bridge creates handlers based on
the first two combinations (the latter two combinations will be added
later). This makes the handler creation mechanism consistent with it's
counterpart in xdbc-bridge.
For that, it was necessary to make both IBridgeHelper methods
"getMainURI()" and "getPingURI()" pure virtual so that derived classes
(LibraryBridgeHelper and XDBCBridgeHelper) must provide custom URLs with
custom paths.
Side note 1: Previously, LibraryBridgeHelper sent HTTP URL parameter
"method=ping" during handshake (PING) but the library-bridge ignored
that parameter. We now omit this parameter, i.e.
LibraryBridgeHelper::PING was removed. Again, this makes things
consistent with xdbc-bridge.
Side note 2: xdbc-bridge is unchanged in this commit. Therefore,
XDBCBridgeHelper now uses the HTTP paths previously in the base class.
For funny reason, XDBCBridgeHelper did not use
IBridgeHelper::getMainURI() - it generates the URLs by itself. I kept it
that way for now but provided an implementation of getMainURI() anyways.
2022-08-04 18:33:13 +00:00
|
|
|
{
|
|
|
|
auto uri = createBaseURI();
|
|
|
|
uri.setPath(PING_HANDLER);
|
|
|
|
uri.addQueryParameter("dictionary_id", toString(dictionary_id));
|
|
|
|
return uri;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
Poco::URI ExternalDictionaryLibraryBridgeHelper::getMainURI() const
|
Prepare server-side BridgeHelper for catboost integration
Wall of text, sorry, but I also had to document some stuff for myself:
There are three ways to communicate data using HTTP:
- the HTTP verb: for our purposes, PUT and GET,
- the HTTP path: '/ping', '/request' etc.,
- the HTTP URL parameter(s), e.g. 'method=libNew&dictionary_id=1234'
The bridge will use different handlers for communication with the
external dictionary library and for communication with the catboost
library. Handlers are created based on a combination of the HTTP verb
and the HTTP method. More specifically, there will be combinations
- GET + '/extdict_ping'
- PUT + '/extdict_request'
- GET + '/catboost_ping'
- PUT + '/catboost_request'.
For each combination, the bridge expects a certain set of URL
parameters, e.g. for the first combination parameter "dictionary_id" is
expected.
Starting with this commit, the library-bridge creates handlers based on
the first two combinations (the latter two combinations will be added
later). This makes the handler creation mechanism consistent with it's
counterpart in xdbc-bridge.
For that, it was necessary to make both IBridgeHelper methods
"getMainURI()" and "getPingURI()" pure virtual so that derived classes
(LibraryBridgeHelper and XDBCBridgeHelper) must provide custom URLs with
custom paths.
Side note 1: Previously, LibraryBridgeHelper sent HTTP URL parameter
"method=ping" during handshake (PING) but the library-bridge ignored
that parameter. We now omit this parameter, i.e.
LibraryBridgeHelper::PING was removed. Again, this makes things
consistent with xdbc-bridge.
Side note 2: xdbc-bridge is unchanged in this commit. Therefore,
XDBCBridgeHelper now uses the HTTP paths previously in the base class.
For funny reason, XDBCBridgeHelper did not use
IBridgeHelper::getMainURI() - it generates the URLs by itself. I kept it
that way for now but provided an implementation of getMainURI() anyways.
2022-08-04 18:33:13 +00:00
|
|
|
{
|
|
|
|
auto uri = createBaseURI();
|
|
|
|
uri.setPath(MAIN_HANDLER);
|
|
|
|
return uri;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
Poco::URI ExternalDictionaryLibraryBridgeHelper::createRequestURI(const String & method) const
|
2021-03-05 09:38:00 +00:00
|
|
|
{
|
2021-03-07 11:31:55 +00:00
|
|
|
auto uri = getMainURI();
|
2022-08-08 14:40:19 +00:00
|
|
|
uri.addQueryParameter("version", std::to_string(LIBRARY_BRIDGE_PROTOCOL_VERSION));
|
2021-03-22 14:39:17 +00:00
|
|
|
uri.addQueryParameter("dictionary_id", toString(dictionary_id));
|
2021-03-24 09:23:29 +00:00
|
|
|
uri.addQueryParameter("method", method);
|
2021-03-05 09:38:00 +00:00
|
|
|
return uri;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
bool ExternalDictionaryLibraryBridgeHelper::bridgeHandShake()
|
2021-03-05 09:38:00 +00:00
|
|
|
{
|
2021-07-30 14:20:57 +00:00
|
|
|
String result;
|
|
|
|
try
|
|
|
|
{
|
Prepare server-side BridgeHelper for catboost integration
Wall of text, sorry, but I also had to document some stuff for myself:
There are three ways to communicate data using HTTP:
- the HTTP verb: for our purposes, PUT and GET,
- the HTTP path: '/ping', '/request' etc.,
- the HTTP URL parameter(s), e.g. 'method=libNew&dictionary_id=1234'
The bridge will use different handlers for communication with the
external dictionary library and for communication with the catboost
library. Handlers are created based on a combination of the HTTP verb
and the HTTP method. More specifically, there will be combinations
- GET + '/extdict_ping'
- PUT + '/extdict_request'
- GET + '/catboost_ping'
- PUT + '/catboost_request'.
For each combination, the bridge expects a certain set of URL
parameters, e.g. for the first combination parameter "dictionary_id" is
expected.
Starting with this commit, the library-bridge creates handlers based on
the first two combinations (the latter two combinations will be added
later). This makes the handler creation mechanism consistent with it's
counterpart in xdbc-bridge.
For that, it was necessary to make both IBridgeHelper methods
"getMainURI()" and "getPingURI()" pure virtual so that derived classes
(LibraryBridgeHelper and XDBCBridgeHelper) must provide custom URLs with
custom paths.
Side note 1: Previously, LibraryBridgeHelper sent HTTP URL parameter
"method=ping" during handshake (PING) but the library-bridge ignored
that parameter. We now omit this parameter, i.e.
LibraryBridgeHelper::PING was removed. Again, this makes things
consistent with xdbc-bridge.
Side note 2: xdbc-bridge is unchanged in this commit. Therefore,
XDBCBridgeHelper now uses the HTTP paths previously in the base class.
For funny reason, XDBCBridgeHelper did not use
IBridgeHelper::getMainURI() - it generates the URLs by itself. I kept it
that way for now but provided an implementation of getMainURI() anyways.
2022-08-04 18:33:13 +00:00
|
|
|
ReadWriteBufferFromHTTP buf(getPingURI(), Poco::Net::HTTPRequest::HTTP_GET, {}, http_timeouts, credentials);
|
2021-07-30 14:20:57 +00:00
|
|
|
readString(result, buf);
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
2021-10-13 11:24:12 +00:00
|
|
|
tryLogCurrentException(log);
|
2021-07-30 14:20:57 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* When pinging bridge we also pass current dicionary_id. The bridge will check if there is such
|
|
|
|
* dictionary. It is possible that such dictionary_id is not present only in two cases:
|
|
|
|
* 1. It is dictionary source creation and initialization of library handler on bridge side did not happen yet.
|
|
|
|
* 2. Bridge crashed or restarted for some reason while server did not.
|
|
|
|
**/
|
2021-08-02 07:18:51 +00:00
|
|
|
if (result.size() != 1)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::LOGICAL_ERROR,
|
|
|
|
"Unexpected message from library bridge: {}. "
|
|
|
|
"Check that bridge and server have the same version.", result);
|
2021-07-30 14:20:57 +00:00
|
|
|
|
|
|
|
UInt8 dictionary_id_exists;
|
2021-08-02 07:18:51 +00:00
|
|
|
auto parsed = tryParse<UInt8>(dictionary_id_exists, result);
|
2021-07-30 14:20:57 +00:00
|
|
|
if (!parsed || (dictionary_id_exists != 0 && dictionary_id_exists != 1))
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::LOGICAL_ERROR,
|
|
|
|
"Unexpected message from library bridge: {} ({}). "
|
|
|
|
"Check that bridge and server have the same version.",
|
2021-07-30 14:20:57 +00:00
|
|
|
result, parsed ? toString(dictionary_id_exists) : "failed to parse");
|
|
|
|
|
2021-08-01 09:56:48 +00:00
|
|
|
LOG_TRACE(log, "dictionary_id: {}, dictionary_id_exists on bridge side: {}, library confirmed to be initialized on server side: {}",
|
|
|
|
toString(dictionary_id), toString(dictionary_id_exists), library_initialized);
|
|
|
|
|
2021-07-30 14:20:57 +00:00
|
|
|
if (dictionary_id_exists && !library_initialized)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::LOGICAL_ERROR,
|
|
|
|
"Library was not initialized, but bridge responded to already have dictionary id: {}",
|
|
|
|
dictionary_id);
|
2021-07-30 14:20:57 +00:00
|
|
|
|
2021-08-02 07:18:51 +00:00
|
|
|
/// Here we want to say bridge to recreate a new library handler for current dictionary,
|
|
|
|
/// because it responded to have lost it, but we know that it has already been created. (It is a direct result of bridge crash).
|
2021-07-30 14:20:57 +00:00
|
|
|
if (!dictionary_id_exists && library_initialized)
|
|
|
|
{
|
|
|
|
LOG_WARNING(log, "Library bridge does not have library handler with dictionaty id: {}. It will be reinitialized.", dictionary_id);
|
2021-08-01 09:56:48 +00:00
|
|
|
bool reinitialized = false;
|
2021-07-30 14:20:57 +00:00
|
|
|
try
|
|
|
|
{
|
2022-08-03 11:19:13 +00:00
|
|
|
auto uri = createRequestURI(EXT_DICT_LIB_NEW_METHOD);
|
2021-08-02 07:18:51 +00:00
|
|
|
reinitialized = executeRequest(uri, getInitLibraryCallback());
|
2021-07-30 14:20:57 +00:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
tryLogCurrentException(log);
|
|
|
|
return false;
|
|
|
|
}
|
2021-08-01 09:56:48 +00:00
|
|
|
|
|
|
|
if (!reinitialized)
|
|
|
|
throw Exception(ErrorCodes::EXTERNAL_LIBRARY_ERROR,
|
|
|
|
"Failed to reinitialize library handler on bridge side for dictionary with id: {}", dictionary_id);
|
2021-07-30 14:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2021-04-02 15:45:42 +00:00
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
ReadWriteBufferFromHTTP::OutStreamCallback ExternalDictionaryLibraryBridgeHelper::getInitLibraryCallback() const
|
2021-07-30 14:20:57 +00:00
|
|
|
{
|
2021-04-02 15:45:42 +00:00
|
|
|
/// Sample block must contain null values
|
|
|
|
WriteBufferFromOwnString out;
|
2022-08-04 19:19:04 +00:00
|
|
|
auto output_format = getContext()->getOutputFormat(ExternalDictionaryLibraryBridgeHelper::DEFAULT_FORMAT, out, sample_block);
|
2021-10-11 16:11:50 +00:00
|
|
|
formatBlock(output_format, sample_block);
|
2021-04-02 15:45:42 +00:00
|
|
|
auto block_string = out.str();
|
|
|
|
|
2021-07-30 14:20:57 +00:00
|
|
|
return [block_string, this](std::ostream & os)
|
2021-03-24 08:41:42 +00:00
|
|
|
{
|
2021-07-30 14:20:57 +00:00
|
|
|
os << "library_path=" << escapeForFileName(library_data.library_path) << "&";
|
|
|
|
os << "library_settings=" << escapeForFileName(library_data.library_settings) << "&";
|
|
|
|
os << "attributes_names=" << escapeForFileName(library_data.dict_attributes) << "&";
|
2021-04-02 15:45:42 +00:00
|
|
|
os << "sample_block=" << escapeForFileName(sample_block.getNamesAndTypesList().toString()) << "&";
|
2021-04-05 13:13:07 +00:00
|
|
|
os << "null_values=" << escapeForFileName(block_string);
|
2021-04-02 15:45:42 +00:00
|
|
|
};
|
2021-07-30 14:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
bool ExternalDictionaryLibraryBridgeHelper::initLibrary()
|
2021-07-30 14:20:57 +00:00
|
|
|
{
|
2021-08-02 07:18:51 +00:00
|
|
|
startBridgeSync();
|
2022-08-03 11:19:13 +00:00
|
|
|
auto uri = createRequestURI(EXT_DICT_LIB_NEW_METHOD);
|
2021-08-02 07:18:51 +00:00
|
|
|
library_initialized = executeRequest(uri, getInitLibraryCallback());
|
|
|
|
return library_initialized;
|
2021-03-05 09:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
bool ExternalDictionaryLibraryBridgeHelper::cloneLibrary(const Field & other_dictionary_id)
|
2021-03-05 09:38:00 +00:00
|
|
|
{
|
2021-03-07 11:06:52 +00:00
|
|
|
startBridgeSync();
|
2022-08-03 11:19:13 +00:00
|
|
|
auto uri = createRequestURI(EXT_DICT_LIB_CLONE_METHOD);
|
2021-03-22 14:39:17 +00:00
|
|
|
uri.addQueryParameter("from_dictionary_id", toString(other_dictionary_id));
|
2021-08-02 07:18:51 +00:00
|
|
|
/// We also pass initialization settings in order to create a library handler
|
|
|
|
/// in case from_dictionary_id does not exist in bridge side (possible in case of bridge crash).
|
|
|
|
library_initialized = executeRequest(uri, getInitLibraryCallback());
|
|
|
|
return library_initialized;
|
2021-03-05 10:43:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
bool ExternalDictionaryLibraryBridgeHelper::removeLibrary()
|
2021-03-05 15:37:43 +00:00
|
|
|
{
|
2021-07-30 14:20:57 +00:00
|
|
|
/// Do not force bridge restart if it is not running in case of removeLibrary
|
|
|
|
/// because in this case after restart it will not have this dictionaty id in memory anyway.
|
2021-08-02 07:18:51 +00:00
|
|
|
if (bridgeHandShake())
|
2021-07-30 14:20:57 +00:00
|
|
|
{
|
2022-08-03 11:19:13 +00:00
|
|
|
auto uri = createRequestURI(EXT_DICT_LIB_DELETE_METHOD);
|
2021-07-30 14:20:57 +00:00
|
|
|
return executeRequest(uri);
|
|
|
|
}
|
|
|
|
return true;
|
2021-03-05 15:37:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
bool ExternalDictionaryLibraryBridgeHelper::isModified()
|
2021-03-05 10:43:47 +00:00
|
|
|
{
|
2021-03-07 11:06:52 +00:00
|
|
|
startBridgeSync();
|
2022-08-03 11:19:13 +00:00
|
|
|
auto uri = createRequestURI(EXT_DICT_IS_MODIFIED_METHOD);
|
2021-03-10 18:02:43 +00:00
|
|
|
return executeRequest(uri);
|
2021-03-05 10:43:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
bool ExternalDictionaryLibraryBridgeHelper::supportsSelectiveLoad()
|
2021-03-05 10:43:47 +00:00
|
|
|
{
|
2021-03-07 11:06:52 +00:00
|
|
|
startBridgeSync();
|
2022-08-03 11:19:13 +00:00
|
|
|
auto uri = createRequestURI(EXT_DICT_SUPPORTS_SELECTIVE_LOAD_METHOD);
|
2021-03-10 18:02:43 +00:00
|
|
|
return executeRequest(uri);
|
2021-03-05 09:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
QueryPipeline ExternalDictionaryLibraryBridgeHelper::loadAll()
|
2021-03-05 09:38:00 +00:00
|
|
|
{
|
2021-03-07 11:06:52 +00:00
|
|
|
startBridgeSync();
|
2022-08-03 11:19:13 +00:00
|
|
|
auto uri = createRequestURI(EXT_DICT_LOAD_ALL_METHOD);
|
2022-05-20 19:49:31 +00:00
|
|
|
return QueryPipeline(loadBase(uri));
|
2021-03-05 09:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-08 14:04:41 +00:00
|
|
|
static String getDictIdsString(const std::vector<UInt64> & ids)
|
|
|
|
{
|
|
|
|
WriteBufferFromOwnString out;
|
|
|
|
writeVectorBinary(ids, out);
|
|
|
|
return out.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
QueryPipeline ExternalDictionaryLibraryBridgeHelper::loadIds(const std::vector<uint64_t> & ids)
|
2021-03-05 09:38:00 +00:00
|
|
|
{
|
2021-03-07 11:06:52 +00:00
|
|
|
startBridgeSync();
|
2022-08-03 11:19:13 +00:00
|
|
|
auto uri = createRequestURI(EXT_DICT_LOAD_IDS_METHOD);
|
2021-08-01 08:51:40 +00:00
|
|
|
uri.addQueryParameter("ids_num", toString(ids.size())); /// Not used parameter, but helpful
|
2021-08-01 09:56:48 +00:00
|
|
|
auto ids_string = getDictIdsString(ids);
|
2022-05-20 19:49:31 +00:00
|
|
|
return QueryPipeline(loadBase(uri, [ids_string](std::ostream & os) { os << ids_string; }));
|
2021-03-05 09:38:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
QueryPipeline ExternalDictionaryLibraryBridgeHelper::loadKeys(const Block & requested_block)
|
2021-03-06 18:44:40 +00:00
|
|
|
{
|
2021-03-07 11:06:52 +00:00
|
|
|
startBridgeSync();
|
2022-08-03 11:19:13 +00:00
|
|
|
auto uri = createRequestURI(EXT_DICT_LOAD_KEYS_METHOD);
|
2021-03-24 07:53:15 +00:00
|
|
|
/// Sample block to parse block from callback
|
2021-03-24 09:23:29 +00:00
|
|
|
uri.addQueryParameter("requested_block_sample", requested_block.getNamesAndTypesList().toString());
|
|
|
|
ReadWriteBufferFromHTTP::OutStreamCallback out_stream_callback = [requested_block, this](std::ostream & os)
|
2021-03-10 13:10:05 +00:00
|
|
|
{
|
2021-03-24 07:53:15 +00:00
|
|
|
WriteBufferFromOStream out_buffer(os);
|
2022-08-04 19:19:04 +00:00
|
|
|
auto output_format = getContext()->getOutputFormat(ExternalDictionaryLibraryBridgeHelper::DEFAULT_FORMAT, out_buffer, requested_block.cloneEmpty());
|
2021-10-11 16:11:50 +00:00
|
|
|
formatBlock(output_format, requested_block);
|
2021-03-10 13:10:05 +00:00
|
|
|
};
|
2022-05-20 19:49:31 +00:00
|
|
|
return QueryPipeline(loadBase(uri, out_stream_callback));
|
2021-03-10 18:02:43 +00:00
|
|
|
}
|
2021-03-10 13:10:05 +00:00
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
bool ExternalDictionaryLibraryBridgeHelper::executeRequest(const Poco::URI & uri, ReadWriteBufferFromHTTP::OutStreamCallback out_stream_callback) const
|
2021-03-10 18:02:43 +00:00
|
|
|
{
|
|
|
|
ReadWriteBufferFromHTTP buf(
|
|
|
|
uri,
|
|
|
|
Poco::Net::HTTPRequest::HTTP_POST,
|
2021-03-24 08:41:42 +00:00
|
|
|
std::move(out_stream_callback),
|
2021-10-28 10:28:05 +00:00
|
|
|
http_timeouts, credentials);
|
2021-03-10 13:10:05 +00:00
|
|
|
|
2021-03-10 18:02:43 +00:00
|
|
|
bool res;
|
|
|
|
readBoolText(res, buf);
|
|
|
|
return res;
|
|
|
|
}
|
2021-03-10 13:10:05 +00:00
|
|
|
|
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
QueryPipeline ExternalDictionaryLibraryBridgeHelper::loadBase(const Poco::URI & uri, ReadWriteBufferFromHTTP::OutStreamCallback out_stream_callback)
|
2021-03-10 18:02:43 +00:00
|
|
|
{
|
|
|
|
auto read_buf_ptr = std::make_unique<ReadWriteBufferFromHTTP>(
|
|
|
|
uri,
|
|
|
|
Poco::Net::HTTPRequest::HTTP_POST,
|
|
|
|
std::move(out_stream_callback),
|
2021-08-03 19:47:59 +00:00
|
|
|
http_timeouts,
|
2021-10-27 18:30:25 +00:00
|
|
|
credentials,
|
2021-10-28 10:28:05 +00:00
|
|
|
0,
|
2021-03-10 18:02:43 +00:00
|
|
|
DBMS_DEFAULT_BUFFER_SIZE,
|
2021-10-07 13:39:54 +00:00
|
|
|
getContext()->getReadSettings(),
|
2022-12-16 22:57:09 +00:00
|
|
|
HTTPHeaderEntries{});
|
2021-03-10 18:02:43 +00:00
|
|
|
|
2022-08-04 19:19:04 +00:00
|
|
|
auto source = FormatFactory::instance().getInput(ExternalDictionaryLibraryBridgeHelper::DEFAULT_FORMAT, *read_buf_ptr, sample_block, getContext(), DEFAULT_BLOCK_SIZE);
|
2021-08-05 18:08:52 +00:00
|
|
|
source->addBuffer(std::move(read_buf_ptr));
|
2022-05-20 19:49:31 +00:00
|
|
|
return QueryPipeline(std::move(source));
|
2021-03-06 18:44:40 +00:00
|
|
|
}
|
|
|
|
|
2021-08-06 08:41:45 +00:00
|
|
|
}
|