Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#209] Create links using template #271

Merged
merged 4 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/link_creation_agent/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ services:
ports:
- 37007:37007
volumes:
- ../../../src:/opt
- ../../src:/opt
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using relative paths can cause some issues.
Is there any other way to do it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I'll rewrite the compose, rn is just for local testing

depends_on:
- mongodb
- redis
Expand All @@ -97,7 +97,7 @@ services:
ports:
- 35700:35700
volumes:
- ../../../src:/opt
- ../../src:/opt
restart: on-failure
depends_on:
- mongodb
Expand All @@ -121,7 +121,7 @@ services:
command: ./bin/link_creation_server --type server --config_file /tmp/config
volumes:
- ./data:/tmp
- ../../../src:/opt
- ../../src:/opt
ports:
- 9090:9090
restart: on-failure
Expand Down
1 change: 1 addition & 0 deletions src/link_creation_agent/das_link_creation_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class LinkCreationNode : public StarNode {
private:
Queue<vector<string>> shared_queue;
const string CREATE_LINK = "create_link"; // DAS Node command
const string CREATE_LINK_PROCESSOR = "create_link_processor";
bool shutting_down = false;
bool is_server = true;
};
Expand Down
110 changes: 60 additions & 50 deletions src/link_creation_agent/link.cc
Original file line number Diff line number Diff line change
@@ -1,73 +1,83 @@
#include "link.h"
#include <iostream>

#include <iostream>

using namespace link_creation_agent;
using namespace std;
using namespace query_engine;


Link::Link(string type, vector<string> targets)
{
this->type = type;
this->targets = targets;
}

Link::Link(QueryAnswer *query_answer, vector<string> link_template)
{
string query_tokens = query_answer->tokenize();
string token = "";
for(char token_char : query_tokens){
if(token_char == ' '){
this->targets.push_back(token);
token = "";
}else{
token += token_char;
Link::Link(QueryAnswer* query_answer, vector<string> link_template) {
LinkCreateTemplate link_create_template(link_template);
HandlesAnswer* handles_answer = dynamic_cast<HandlesAnswer*>(query_answer);

this->type = link_create_template.get_link_type();
vector<LinkCreateTemplateTypes> targets = link_create_template.get_targets();
for (LinkCreateTemplateTypes target : targets) {
if (holds_alternative<Variable>(target)) {
string token = get<Variable>(target).name;
this->targets.push_back(handles_answer->assignment.get(token.c_str()));
}
if (holds_alternative<std::shared_ptr<LinkCreateTemplate>>(target)) {
shared_ptr<LinkCreateTemplate> sub_link = get<std::shared_ptr<LinkCreateTemplate>>(target);
shared_ptr<Link> sub_link_obj = make_shared<Link>(query_answer, sub_link);
this->targets.push_back(sub_link_obj);
}
}
this->custom_fields = link_create_template.get_custom_fields();
}


Link::Link()
{
}

Link::~Link()
{
Link::Link(QueryAnswer* query_answer, shared_ptr<LinkCreateTemplate> link_create_template) {
HandlesAnswer* handles_answer = dynamic_cast<HandlesAnswer*>(query_answer);
this->type = link_create_template->get_link_type();
vector<LinkCreateTemplateTypes> targets = link_create_template->get_targets();
for (LinkCreateTemplateTypes target : targets) {
if (holds_alternative<Variable>(target)) {
string token = get<Variable>(target).name;
this->targets.push_back(handles_answer->assignment.get(token.c_str()));
}
if (holds_alternative<std::shared_ptr<LinkCreateTemplate>>(target)) {
shared_ptr<LinkCreateTemplate> sub_link = get<std::shared_ptr<LinkCreateTemplate>>(target);
shared_ptr<Link> sub_link_obj = make_shared<Link>(query_answer, sub_link);
this->targets.push_back(sub_link_obj);
}
}
this->custom_fields = link_create_template->get_custom_fields();
}

string Link::get_type()
{
return this->type;
}
Link::Link() {}

vector<string> Link::get_targets()
{
return this->targets;
}
Link::~Link() {}

void Link::set_type(string type)
{
this->type = type;
}
string Link::get_type() { return this->type; }

void Link::set_targets(vector<string> targets)
{
this->targets = targets;
}
vector<LinkTargetTypes> Link::get_targets() { return this->targets; }

void Link::add_target(string target)
{
this->targets.push_back(target);
}
void Link::set_type(string type) { this->type = type; }

vector<string> Link::tokenize()
{
return targets;
}

void Link::add_target(LinkTargetTypes target) { this->targets.push_back(target); }

Link Link::untokenize(string link)
{
return Link();
vector<string> Link::tokenize() {
vector<string> tokens;
tokens.push_back("LINK");
tokens.push_back(this->type);
for (LinkTargetTypes target : this->targets) {
if (holds_alternative<string>(target)) {
tokens.push_back("HANDLE");
tokens.push_back(get<string>(target));
}
if (holds_alternative<shared_ptr<Link>>(target)) {
for (string token : get<shared_ptr<Link>>(target)->tokenize()) {
tokens.push_back(token);
}
}
}
for (CustomField custom_field : this->custom_fields) {
for (string token : custom_field.tokenize()) {
tokens.push_back(token);
}
}
return tokens;
}
23 changes: 14 additions & 9 deletions src/link_creation_agent/link.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,26 @@
#pragma once
#include <string>
#include <vector>
#include <variant>
#include "QueryAnswer.h"
#include "HandlesAnswer.h"
#include "link_create_template.h"

using namespace std;
using namespace query_engine;

namespace link_creation_agent
{

class Link; // forward declaration

using LinkTargetTypes = std::variant<std::string, std::shared_ptr<Link>>;

class Link
{
public:
Link(string type, vector<string> targets);
Link(QueryAnswer *query_answer, vector<string> link_template);
Link(QueryAnswer *query_answer, shared_ptr<LinkCreateTemplate> link_create_template);
Link();
~Link();
/**
Expand All @@ -29,29 +36,27 @@ namespace link_creation_agent
* @brief Get the targets of the link
* @returns Returns the targets of the link
*/
vector<string> get_targets();
vector<LinkTargetTypes> get_targets();
/**
* @brief Set the type of the link
*/
void set_type(string type);
/**
* @brief Set the targets of the link
*/
void set_targets(vector<string> targets);
/**
* @brief Add a target to the link
* @param target Target to be added
*/
void add_target(string target);
void add_target(LinkTargetTypes target);
/**
* @brief Tokenize the link
* @returns Returns the tokenized link
*/
vector<string> tokenize();
Link untokenize(string link);

private:
string type;
vector<string> targets;
vector<LinkTargetTypes> targets;
vector<CustomField> custom_fields;


};
}
125 changes: 70 additions & 55 deletions src/link_creation_agent/link_create_template.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <algorithm>
#include <iostream>
#include <sstream>
#include <stdexcept>

using namespace link_creation_agent;
Expand All @@ -25,61 +26,19 @@ static std::string get_token(std::vector<std::string>& link_template, int cursor
}
return link_template[cursor];
}

CustomField::CustomField(std::vector<std::string>& custom_fields) {
if (get_token(custom_fields, 0) != "CUSTOM_FIELD")
throw std::invalid_argument("Can not create Custom Field: Invalid arguments");

int cursor = 0;
std::string custom_field_name = get_token(custom_fields, 1);
this->name = custom_field_name;
cursor += 3;
while (cursor < custom_fields.size()) {
if (get_token(custom_fields, cursor) == "CUSTOM_FIELD") {
std::vector<std::string> custom_field_args;
int sub_custom_field_size = string_to_int(get_token(custom_fields, cursor + 2));
std::string sub_custom_field_name = get_token(custom_fields, cursor + 1);
custom_field_args.push_back(get_token(custom_fields, cursor)); // CUSTOM_FIELD
custom_field_args.push_back(get_token(custom_fields, cursor + 1)); // field name
custom_field_args.push_back(get_token(custom_fields, cursor + 2)); // field size
cursor += 3;
while (cursor < custom_fields.size()) {
if (sub_custom_field_size == 0) {
break;
}

custom_field_args.push_back(get_token(custom_fields, cursor));
if (get_token(custom_fields, cursor) == "CUSTOM_FIELD") {
sub_custom_field_size += string_to_int(get_token(custom_fields, cursor + 2));
custom_field_args.push_back(get_token(custom_fields, cursor + 1)); // field name
custom_field_args.push_back(get_token(custom_fields, cursor + 2)); // field size
cursor += 3;
sub_custom_field_size--;
} else {
custom_field_args.push_back(get_token(custom_fields, cursor + 1));
cursor += 2;
sub_custom_field_size--;
}
}
CustomField custom_field = CustomField(custom_field_args);
this->values.push_back(
std::make_tuple(sub_custom_field_name, std::make_shared<CustomField>(custom_field)));
} else {
this->values.push_back(
std::make_tuple(get_token(custom_fields, cursor), get_token(custom_fields, cursor + 1)));
cursor += 2;
}
// TODO move this to a utils file
static std::vector<std::string> split(const std::string& s, char delimiter) {
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(s);
while (std::getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}

CustomField::~CustomField() {}

std::string CustomField::get_name() { return this->name; }

std::vector<std::tuple<std::string, CustomFieldTypes>> CustomField::get_values() { return this->values; }

std::vector<std::string> parse_sub_custom_field(std::vector<std::string>& link_template,
size_t& cursor) {
static std::vector<std::string> parse_sub_custom_field(std::vector<std::string>& link_template,
size_t& cursor) {
if (get_token(link_template, cursor) != "CUSTOM_FIELD" || link_template.size() < cursor + 3)
throw std::invalid_argument("Can not create Custom Field: Invalid arguments");
std::vector<std::string> custom_field_args;
Expand Down Expand Up @@ -108,8 +67,8 @@ std::vector<std::string> parse_sub_custom_field(std::vector<std::string>& link_t
return custom_field_args;
}

std::vector<std::string> parse_sub_link_template(std::vector<std::string>& link_template,
size_t& cursor) {
static std::vector<std::string> parse_sub_link_template(std::vector<std::string>& link_template,
size_t& cursor) {
if (get_token(link_template, cursor) != "LINK_CREATE" || link_template.size() < cursor + 4)
throw std::invalid_argument("Can not create Link Template: Invalid arguments");
int sub_link_template_size = string_to_int(get_token(link_template, cursor + 2));
Expand Down Expand Up @@ -226,6 +185,60 @@ std::string LinkCreateTemplate::to_string() {
return link_template;
}

std::vector<std::string> LinkCreateTemplate::tokenize() { return split(this->to_string(), ' '); }

CustomField::CustomField(std::vector<std::string>& custom_fields) {
if (get_token(custom_fields, 0) != "CUSTOM_FIELD")
throw std::invalid_argument("Can not create Custom Field: Invalid arguments");

int cursor = 0;
std::string custom_field_name = get_token(custom_fields, 1);
this->name = custom_field_name;
cursor += 3;
while (cursor < custom_fields.size()) {
if (get_token(custom_fields, cursor) == "CUSTOM_FIELD") {
std::vector<std::string> custom_field_args;
int sub_custom_field_size = string_to_int(get_token(custom_fields, cursor + 2));
std::string sub_custom_field_name = get_token(custom_fields, cursor + 1);
custom_field_args.push_back(get_token(custom_fields, cursor)); // CUSTOM_FIELD
custom_field_args.push_back(get_token(custom_fields, cursor + 1)); // field name
custom_field_args.push_back(get_token(custom_fields, cursor + 2)); // field size
cursor += 3;
while (cursor < custom_fields.size()) {
if (sub_custom_field_size == 0) {
break;
}

custom_field_args.push_back(get_token(custom_fields, cursor));
if (get_token(custom_fields, cursor) == "CUSTOM_FIELD") {
sub_custom_field_size += string_to_int(get_token(custom_fields, cursor + 2));
custom_field_args.push_back(get_token(custom_fields, cursor + 1)); // field name
custom_field_args.push_back(get_token(custom_fields, cursor + 2)); // field size
cursor += 3;
sub_custom_field_size--;
} else {
custom_field_args.push_back(get_token(custom_fields, cursor + 1));
cursor += 2;
sub_custom_field_size--;
}
}
CustomField custom_field = CustomField(custom_field_args);
this->values.push_back(
std::make_tuple(sub_custom_field_name, std::make_shared<CustomField>(custom_field)));
} else {
this->values.push_back(
std::make_tuple(get_token(custom_fields, cursor), get_token(custom_fields, cursor + 1)));
cursor += 2;
}
}
}

CustomField::~CustomField() {}

std::string CustomField::get_name() { return this->name; }

std::vector<std::tuple<std::string, CustomFieldTypes>> CustomField::get_values() { return this->values; }

std::string CustomField::to_string() {
std::string custom_field =
"CUSTOM_FIELD " + this->name + " " + std::to_string(this->values.size()) + " ";
Expand All @@ -241,4 +254,6 @@ std::string CustomField::to_string() {
}
}
return custom_field;
}
}

std::vector<std::string> CustomField::tokenize() { return split(this->to_string(), ' '); }
Loading