2022-01-27 16:22:05 +00:00
|
|
|
#include <Formats/FormatFactory.h>
|
|
|
|
#include <IO/WriteBufferFromString.h>
|
|
|
|
#include <Processors/Formats/Impl/JSONRowOutputFormat.h>
|
2021-12-30 18:11:12 +00:00
|
|
|
#include <Storages/MeiliSearch/SinkMeiliSearch.h>
|
2022-01-27 16:22:05 +00:00
|
|
|
#include <base/JSON.h>
|
|
|
|
#include <base/types.h>
|
2021-12-30 18:11:12 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int MEILISEARCH_EXCEPTION;
|
|
|
|
}
|
|
|
|
|
2022-01-27 16:22:05 +00:00
|
|
|
SinkMeiliSearch::SinkMeiliSearch(const MeiliSearchConfiguration & config_, const Block & sample_block_, ContextPtr local_context_)
|
|
|
|
: SinkToStorage(sample_block_), connection(config_), local_context{local_context_}, sample_block{sample_block_}
|
2021-12-31 15:23:29 +00:00
|
|
|
{
|
|
|
|
}
|
2021-12-30 18:11:12 +00:00
|
|
|
|
2022-01-27 16:22:05 +00:00
|
|
|
// gets the content of the json data section, which was obtained using the JSON format output
|
|
|
|
// "data": [{...}, {...}, {...}]
|
|
|
|
void extractData(std::string_view & view)
|
|
|
|
{
|
|
|
|
size_t ind = view.find("\"data\":");
|
|
|
|
while (view[ind] != '[')
|
|
|
|
++ind;
|
2022-01-08 11:08:17 +00:00
|
|
|
view.remove_prefix(ind);
|
2022-01-27 16:22:05 +00:00
|
|
|
size_t bal = ind = 1;
|
|
|
|
while (bal > 0)
|
2022-01-14 17:58:56 +00:00
|
|
|
{
|
2022-01-27 16:22:05 +00:00
|
|
|
if (view[ind] == '[')
|
|
|
|
++bal;
|
|
|
|
else if (view[ind] == ']')
|
|
|
|
--bal;
|
2022-01-08 11:08:17 +00:00
|
|
|
++ind;
|
2022-01-27 16:22:05 +00:00
|
|
|
}
|
2022-01-08 11:08:17 +00:00
|
|
|
view.remove_suffix(view.size() - ind);
|
2021-12-30 18:11:12 +00:00
|
|
|
}
|
|
|
|
|
2021-12-31 15:23:29 +00:00
|
|
|
void SinkMeiliSearch::writeBlockData(const Block & block) const
|
|
|
|
{
|
2022-01-08 11:08:17 +00:00
|
|
|
FormatSettings settings = getFormatSettings(local_context);
|
|
|
|
settings.json.quote_64bit_integers = false;
|
|
|
|
WriteBufferFromOwnString buf;
|
2022-10-28 16:41:10 +00:00
|
|
|
auto writer = FormatFactory::instance().getOutputFormat("JSON", buf, sample_block, local_context, settings);
|
2022-01-08 11:08:17 +00:00
|
|
|
writer->write(block);
|
|
|
|
writer->flush();
|
|
|
|
writer->finalize();
|
|
|
|
|
|
|
|
std::string_view vbuf(buf.str());
|
|
|
|
extractData(vbuf);
|
|
|
|
|
|
|
|
auto response = connection.updateQuery(vbuf);
|
|
|
|
auto jres = JSON(response).begin();
|
2021-12-31 15:23:29 +00:00
|
|
|
if (jres.getName() == "message")
|
2023-01-26 09:52:47 +00:00
|
|
|
throw Exception::createRuntime(ErrorCodes::MEILISEARCH_EXCEPTION, jres.getValue().toString());
|
2021-12-30 18:11:12 +00:00
|
|
|
}
|
|
|
|
|
2021-12-31 15:23:29 +00:00
|
|
|
void SinkMeiliSearch::consume(Chunk chunk)
|
|
|
|
{
|
2021-12-30 18:11:12 +00:00
|
|
|
auto block = getHeader().cloneWithColumns(chunk.detachColumns());
|
2022-01-14 17:58:56 +00:00
|
|
|
writeBlockData(block);
|
2021-12-30 18:11:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|