Skip to content

Commit

Permalink
[7570] Add GenQuery2 API.
Browse files Browse the repository at this point in the history
  • Loading branch information
korydraughn committed Mar 17, 2024
1 parent 329c4e3 commit 80a0825
Show file tree
Hide file tree
Showing 33 changed files with 2,675 additions and 2 deletions.
2 changes: 2 additions & 0 deletions lib/api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ foreach(variant IN ITEMS client server)
"${CMAKE_CURRENT_SOURCE_DIR}/src/rc_check_auth_credentials.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rc_data_object_finalize.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rc_data_object_modify_info.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rc_genquery2.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rc_get_delay_rule_info.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rc_get_file_descriptor_info.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rc_get_grid_configuration_value.cpp"
Expand Down Expand Up @@ -274,6 +275,7 @@ install(
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/fileUnlink.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/fileWrite.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/genQuery.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/genquery2.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/generalAdmin.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/generalRowInsert.h"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/generalRowPurge.h"
Expand Down
1 change: 1 addition & 0 deletions lib/api/include/irods/apiHeaderAll.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,5 +147,6 @@
#include "irods/exec_rule_expression.h"

#include "irods/check_auth_credentials.h"
#include "irods/genquery2.h"

#endif // API_HEADER_ALL_H__
1 change: 1 addition & 0 deletions lib/api/include/irods/apiNumberData.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,6 @@ API_NUMBER(ZONE_REPORT_AN, 10205)
API_NUMBER(CLIENT_HINTS_AN, 10215)

API_NUMBER(GET_RESOURCE_INFO_FOR_OPERATION_AN, 10220)
API_NUMBER(GENQUERY2_AN, 10221)

// clang-format on
11 changes: 11 additions & 0 deletions lib/api/include/irods/apiTable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
# include "irods/rsUserAdmin.hpp"
# include "irods/rsZoneReport.hpp"
# include "irods/rs_check_auth_credentials.hpp"
# include "irods/rs_genquery2.hpp"
# include "irods/rs_get_library_features.hpp"
# include "irods/rs_get_resource_info_for_operation.hpp"
# define NULLPTR_FOR_CLIENT_TABLE(x) x
Expand All @@ -165,6 +166,7 @@
#include <cstdlib>
#include <functional>

// clang-format off
#define RS_AUTHENTICATE NULLPTR_FOR_CLIENT_TABLE(rsAuthenticate)
#define RS_AUTH_CHECK NULLPTR_FOR_CLIENT_TABLE(rsAuthCheck)
#define RS_AUTH_PLUG_REQ NULLPTR_FOR_CLIENT_TABLE(rsAuthPluginRequest)
Expand Down Expand Up @@ -233,6 +235,7 @@
#define RS_GENERAL_ROW_INSERT NULLPTR_FOR_CLIENT_TABLE(rsGeneralRowInsert)
#define RS_GENERAL_ROW_PURGE NULLPTR_FOR_CLIENT_TABLE(rsGeneralRowPurge)
#define RS_GENERAL_UPDATE NULLPTR_FOR_CLIENT_TABLE(rsGeneralUpdate)
#define RS_GENQUERY2 NULLPTR_FOR_CLIENT_TABLE(rs_genquery2)
#define RS_GEN_QUERY NULLPTR_FOR_CLIENT_TABLE(rsGenQuery)
#define RS_GET_HIER_FOR_RESC NULLPTR_FOR_CLIENT_TABLE(rsGetHierarchyForResc)
#define RS_GET_HIER_FROM_LEAF_ID NULLPTR_FOR_CLIENT_TABLE(rsGetHierFromLeafId)
Expand Down Expand Up @@ -302,6 +305,7 @@
#define RS_UNREG_DATA_OBJ NULLPTR_FOR_CLIENT_TABLE(rsUnregDataObj)
#define RS_USER_ADMIN NULLPTR_FOR_CLIENT_TABLE(rsUserAdmin)
#define RS_ZONE_REPORT NULLPTR_FOR_CLIENT_TABLE(rsZoneReport)
// clang-format on

#if defined(CREATE_API_TABLE_FOR_SERVER) && !defined(CREATE_API_TABLE_FOR_CLIENT)
static irods::apidef_t server_api_table_inp[] = {
Expand Down Expand Up @@ -1276,6 +1280,13 @@ static irods::apidef_t client_api_table_inp[] = {
boost::any(std::function<int(rsComm_t*,dataObjInp_t*,char**)>(RS_GET_RESOURCE_INFO_FOR_OPERATION)),
"api_get_resource_info_for_operation", clearDataObjInp, irods::clearOutStruct_noop,
(funcPtr)CALL_GET_RESOURCE_INFO_FOR_OPERATION
},
{
GENQUERY2_AN, RODS_API_VERSION, REMOTE_USER_AUTH, REMOTE_USER_AUTH,
"GenQuery2Input_PI", 0, "STR_PI", 0,
boost::any(std::function<int(rsComm_t*, GenQuery2Input*, char**)>(RS_GENQUERY2)),
"api_genquery2", clearGenQuery2Input, irods::clearOutStruct_noop,
(funcPtr) CALL_GENQUERY2_INOUT
}
// clang-format on
}; // _api_table_inp
Expand Down
1 change: 1 addition & 0 deletions lib/api/include/irods/api_pack_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ inline const packInstruct_t api_pack_table_init[] = {
{"GetHierOut_PI", GetHierOut_PI, irods::clearInStruct_noop},
{"ExecRuleExpression_PI", ExecRuleExpression_PI, irods::clearInStruct_noop},
{"CheckAuthCredentialsInput_PI", CheckAuthCredentialsInput_PI, irods::clearInStruct_noop},
{"GenQuery2Input_PI", GenQuery2Input_PI, irods::clearInStruct_noop},
{PACK_TABLE_END_PI, nullptr, irods::clearInStruct_noop},
};

Expand Down
45 changes: 45 additions & 0 deletions lib/api/include/irods/genquery2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef IRODS_GENQUERY2_H
#define IRODS_GENQUERY2_H

/// \file

struct RcComm;

/// The input data type used to invoke #rc_genquery2.
///
/// \since 4.3.2
typedef struct GenQuery2Input // NOLINT(modernize-use-using)
{
/// TODO
///
/// \since 4.3.2
char* query_string;

/// TODO
///
/// \since 4.3.2
char* zone;

/// TODO
///
/// \since 4.3.2
int sql_only;
} genQuery2Inp_t;

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define GenQuery2Input_PI "str *query_string; str *zone; int sql_only;"

#ifdef __cplusplus
extern "C" {
#endif

/// TODO
///
/// \since 4.3.2
int rc_genquery2(struct RcComm* _comm, struct GenQuery2Input* _input, char** _output);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // IRODS_GENQUERY2_H
19 changes: 19 additions & 0 deletions lib/api/src/rc_genquery2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "irods/genquery2.h"

#include "irods/apiNumber.h"
#include "irods/procApiRequest.h"
#include "irods/rodsErrorTable.h"

auto rc_genquery2(RcComm* _comm, GenQuery2Input* _input, char** _output) -> int
{
if (!_input || !_output) {
return SYS_INVALID_INPUT_PARAM;
}

return procApiRequest(_comm,
GENQUERY2_AN,
_input,
nullptr,
reinterpret_cast<void**>(_output), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
nullptr);
} // rc_genquery2
5 changes: 5 additions & 0 deletions lib/core/include/irods/library_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@
/// \since 4.3.1
#define IRODS_HAS_API_ENDPOINT_CHECK_AUTH_CREDENTIALS 202307L

/// Defined if the development library supports #rc_genquery2.
///
/// \since 4.3.1
#define IRODS_HAS_API_ENDPOINT_GENQUERY2 202403L

#endif // IRODS_LIBRARY_FEATURES_H
2 changes: 2 additions & 0 deletions lib/core/include/irods/rcMisc.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ void clearRescQuota(void* _p);

void clearRescQuotaInp(void* _p);

void clearGenQuery2Input(void* _p);

// clang-format off
__attribute__((deprecated("SimpleQuery is deprecated. Use GenQuery or SpecificQuery instead.")))
void clearSimpleQueryOut(void* _p);
Expand Down
14 changes: 14 additions & 0 deletions lib/core/src/rcMisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,20 @@ void clearRescQuota(void* _p)
std::memset(q, 0, sizeof(rescQuota));
} // clearRescQuota

void clearGenQuery2Input(void* _p)
{
if (!_p) {
return;
}

auto* q = static_cast<GenQuery2Input*>(_p);

free_pointer(q->query_string);
free_pointer(q->zone);

std::memset(q, 0, sizeof(GenQuery2Input));
} // clearGenQuery2Input

int
parseMultiStr( char *strInput, strArray_t *strArray ) {
char *startPtr, *endPtr;
Expand Down
66 changes: 65 additions & 1 deletion plugins/database/src/db_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15810,6 +15810,67 @@ auto db_check_auth_credentials_op(irods::plugin_context& _ctx,
}
} // db_check_auth_credentials_op

auto db_execute_genquery2_sql(irods::plugin_context& _ctx,
const char* _sql,
const std::vector<std::string>* _values,
char** _output) -> irods::error
{
if (const auto ret = _ctx.valid(); !ret.ok()) {
return PASS(ret);
}

if (!_sql || !_values || !_output) {
log_db::error("{}: Received one or more null pointers.", __func__);
return ERROR(SYS_INVALID_INPUT_PARAM, "Received one or more null pointers.");
}

*_output = nullptr;

try {
auto [db_instance, db_conn] = irods::experimental::catalog::new_database_connection();

nanodbc::statement stmt{db_conn};
nanodbc::prepare(stmt, _sql);

for (std::vector<std::string>::size_type i = 0; i < _values->size(); ++i) {
stmt.bind(static_cast<short>(i), _values->at(i).c_str());
}

using json = nlohmann::json;

auto json_array = json::array();
auto json_row = json::array();

auto row = nanodbc::execute(stmt);
const auto n_cols = row.columns();

while (row.next()) {
for (std::remove_cvref_t<decltype(n_cols)> i = 0; i < n_cols; ++i) {
json_row.push_back(row.get<std::string>(i, ""));
}

json_array.push_back(json_row);
json_row.clear();
}

*_output = strdup(json_array.dump().c_str());

return SUCCESS();
}
catch (const irods::exception& e) {
log_db::error("{}: {}", __func__, e.client_display_what());
return ERROR(SYS_LIBRARY_ERROR, e.what());
}
catch (const std::exception& e) {
log_db::error("{}: {}", __func__, e.what());
return ERROR(SYS_LIBRARY_ERROR, e.what());
}
catch (...) {
log_db::error("{}: An unknown error was caught.", __func__);
return ERROR(SYS_UNKNOWN_ERROR, "An unknown error was caught.");
}
} // db_execute_genquery2_sql

// =-=-=-=-=-=-=-
//
irods::error db_start_operation( irods::plugin_property_map& _props ) {
Expand Down Expand Up @@ -16218,7 +16279,10 @@ irods::database* plugin_factory(
pg->add_operation<const char*, const char*, const char*, int*>(
DATABASE_OP_CHECK_AUTH_CREDENTIALS,
function<error(plugin_context&, const char*, const char*, const char*, int*)>(db_check_auth_credentials_op));
pg->add_operation<const char*, const std::vector<std::string>*, char**>(
DATABASE_OP_EXECUTE_GENQUERY2_SQL,
function<error(plugin_context&, const char*, const std::vector<std::string>*, char**)>(
db_execute_genquery2_sql));

return pg;

} // plugin_factory
2 changes: 2 additions & 0 deletions server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ add_library(
)

add_subdirectory(core)
add_subdirectory(genquery2)
add_subdirectory(api)
add_subdirectory(icat)
add_subdirectory(re)
Expand All @@ -37,6 +38,7 @@ target_link_objects(
irods_filesystem_path
irods_filesystem_client
irods_filesystem_server
irods_genquery2_parser
irods_user_administration_client
irods_user_administration_server
irods_resource_administration_client
Expand Down
4 changes: 4 additions & 0 deletions server/api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ add_library(
"${CMAKE_CURRENT_SOURCE_DIR}/src/rs_atomic_apply_metadata_operations.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rs_check_auth_credentials.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rs_data_object_finalize.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rs_genquery2.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rs_get_delay_rule_info.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rs_get_file_descriptor_info.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rs_get_grid_configuration_value.cpp"
Expand Down Expand Up @@ -177,6 +178,8 @@ target_include_directories(
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_IRODS_SOURCE_DIR}/plugins/api/include>"
"$<BUILD_INTERFACE:${CMAKE_IRODS_SOURCE_DIR}/server/core/include>"
"$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/server/genquery2>" # For parser.hpp.
"$<BUILD_INTERFACE:${CMAKE_IRODS_SOURCE_DIR}/server/genquery2/include>"
"$<BUILD_INTERFACE:${CMAKE_IRODS_SOURCE_DIR}/lib/administration/user/include>"
"$<BUILD_INTERFACE:${CMAKE_IRODS_SOURCE_DIR}/lib/administration/zone/include>"
PRIVATE
Expand Down Expand Up @@ -205,6 +208,7 @@ install(
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/rs_atomic_apply_metadata_operations.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/rs_check_auth_credentials.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/rs_data_object_finalize.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/rs_genquery2.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/rs_get_delay_rule_info.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/rs_get_file_descriptor_info.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/irods/rs_get_grid_configuration_value.hpp"
Expand Down
15 changes: 15 additions & 0 deletions server/api/include/irods/rs_genquery2.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef IRODS_RS_GENQUERY2_HPP
#define IRODS_RS_GENQUERY2_HPP

/// \file

#include "irods/genquery2.h"

struct RsComm;

/// TODO
///
/// \since 4.3.2
int rs_genquery2(RsComm* _comm, GenQuery2Input* _input, char** _output);

#endif // IRODS_RS_GENQUERY2_HPP
Loading

0 comments on commit 80a0825

Please sign in to comment.