Skip to content
Snippets Groups Projects
Commit 55bb82d6 authored by Daniel Hornung's avatar Daniel Hornung
Browse files

WIP: Retrieve entity.

parent 1eb3edd2
No related branches found
No related tags found
1 merge request!2ENH: Retrieving single entities works on the mex side.
Pipeline #11666 passed with warnings
Pipeline: caosdb-octaveinttest

#11667

    ......@@ -34,6 +34,10 @@
    namespace maoxdb {
    using std::string;
    auto mxFromCaosDBParents(const caosdb::entity::Parents &parents) -> mxArray *;
    auto mxFromCaosDBProperties(const caosdb::entity::Properties &properties) -> mxArray *;
    auto mxFromCaosDBMessages(const caosdb::entity::Messages &messages) -> mxArray *;
    // Exception and error handling ///////////////////////////////////////////////
    /**
    ......@@ -93,25 +97,22 @@ auto mxFromResultSet(const caosdb::transaction::ResultSet &resultSet)
    -> mxArray * {
    auto resSize = resultSet.Size();
    std::array<mwSize, 2> dims = {1, resSize};
    std::vector<string> keys;
    std::vector<const mxArray *> entities;
    // Obtain entities
    for (auto entity : resultSet) {
    keys.push_back(entity.GetName());
    entities.push_back(mxFromCaosDBEntity(entity));
    }
    // auto * result = mxCreateStructArray (2, dims.data(), resSize,
    // int num_keys,
    // const char ** keys
    // )
    return nullptr;
    auto * result = mxMergeScalarStructs(entities);
    return result;
    }
    /**
    * @brief Convert an Entity from libcaosdb to Octave struct mexArray.
    */
    auto mxFromCaosDBEntity(const caosdb::entity::Entity &entity) -> mxArray * {
    std::vector<const char*> keys =
    auto fields = std::vector<const char*>
    {"role",
    "id",
    "versionId",
    ......@@ -126,8 +127,8 @@ auto mxFromCaosDBEntity(const caosdb::entity::Entity &entity) -> mxArray * {
    "warnings",
    "infos"
    };
    std::array<mwSize, 2> dims = {1, (mwSize)keys.size()};
    auto * result = mxCreateStructArray (2, dims.data(), keys.size(), keys.data());
    std::array<mwSize, 2> dims = {1, (mwSize)fields.size()};
    auto * result = mxCreateStructArray(2, dims.data(), fields.size(), fields.data());
    // Fill with scalar values
    mxSetField(result, 0, "role", mxCreateString(entity.GetRole().c_str()));
    mxSetField(result, 0, "id", mxCreateString(entity.GetId().c_str()));
    ......@@ -141,17 +142,107 @@ auto mxFromCaosDBEntity(const caosdb::entity::Entity &entity) -> mxArray * {
    // Parents and Properties
    mxSetField(result, 0, "parents", mxFromCaosDBParents(entity.GetParents()));
    mxSetField(result, 0, "properties", mxFromCaosDBProperties(entity.GetProperties()));
    // message type content
    mxSetField(result, 0, "errors", mxFromCaosDBMessages(entity.GetErrors()));
    mxSetField(result, 0, "warnings", mxFromCaosDBMessages(entity.GetWarnings()));
    mxSetField(result, 0, "infos", mxFromCaosDBMessages(entity.GetInfos()));
    return result;
    }
    // Parents to cell array with structs
    // Parents to struct array
    auto mxFromCaosDBParents(const caosdb::entity::Parents &parents) -> mxArray * {
    std::vector<const char*> fields =
    {"id",
    "name",
    "description"
    };
    std::array<mwSize, 2> fieldDims = {1, (mwSize)fields.size()};
    std::array<mwSize, 2> dims = {1, (mwSize)parents.Size()};
    auto * result = mxCreateStructArray (2, dims.data(), fields.size(), fields.data());
    for (size_t i = 0; i < parents.Size(); ++i) {
    // TODO ///////////////////////////////////////////////////////////////////
    mxCreateCell // TODO Continue here...
    auto parent = entity.GetParents().At(i);
    auto parent = parents.At(i);
    mxSetField(result, i, "id", mxCreateString(parent.GetId().c_str()));
    mxSetField(result, i, "name", mxCreateString(parent.GetName().c_str()));
    // FIXME Add again once upstream is ready.
    // mxSetField(result, i, "description", mxCreateString(parent.GetDescription().c_str()));
    }
    return result;
    }
    // Properties to struct array
    auto mxFromCaosDBProperties(const caosdb::entity::Properties &properties) -> mxArray * {
    std::vector<const char*> fields =
    {"id",
    "name",
    "description",
    "importance",
    "value",
    "unit",
    "datatype"
    };
    std::array<mwSize, 2> fieldDims = {1, (mwSize)fields.size()};
    std::array<mwSize, 2> dims = {1, (mwSize)properties.Size()};
    auto * result = mxCreateStructArray (2, dims.data(), fields.size(), fields.data());
    for (mwIndex i = 0; i < properties.Size(); ++i) {
    auto property = properties.At(i);
    mxSetField(result, i, "id", mxCreateString(property.GetId().c_str()));
    mxSetField(result, i, "name", mxCreateString(property.GetName().c_str()));
    mxSetField(result, i, "description", mxCreateString(property.GetDescription().c_str()));
    mxSetField(result, i, "importance", mxCreateString(property.GetImportance().c_str()));
    mxSetField(result, i, "unit", mxCreateString(property.GetUnit().c_str()));
    mxSetField(result, i, "datatype", mxCreateString(property.GetDatatype().c_str()));
    // Parse value to proper type.
    mxSetField(result, i, "value", mxScalarFromStringValue(property));
    }
    return result;
    }
    // Messages to struct array
    auto mxFromCaosDBMessages(const caosdb::entity::Messages &messages) -> mxArray * {
    std::vector<const char*> fields =
    {"code",
    "description"
    };
    std::array<mwSize, 2> fieldDims = {1, (mwSize)fields.size()};
    std::array<mwSize, 2> dims = {1, (mwSize)messages.Size()};
    auto * result = mxCreateStructArray (2, dims.data(), fields.size(), fields.data());
    for (mwIndex i = 0; i < messages.Size(); ++i) {
    auto message = messages.At(i);
    mxSetField(result, i, "code", mxScalarINT64(message.GetCode()));
    mxSetField(result, i, "description", mxCreateString(message.GetDescription().c_str()));
    }
    return result;
    }
    // Utility functions //////////////////////////////////////////////////////////
    /**
    * @brief Merges a number of scalar mex structs into a 1xN struct.
    */
    auto mxMergeScalarStructs(const std::vector<const mxArray *> &structs) -> mxArray* {
    // We need the field names first to create a new struct
    auto nFields = (size_t)mxGetNumberOfFields(structs[0]);
    auto fields = std::vector<const char*>(nFields);
    for (mwIndex i = 0; i < nFields; ++i) {
    fields[i] = mxGetFieldNameByNumber(structs[0], i);
    }
    auto dims = std::array<mwSize, 2>{1, (mwSize)structs.size()};
    auto result = mxCreateStructArray(2, dims.data(), fields.size(), fields.data());
    auto i = mwIndex(0) - 1;
    for (auto scalarStruct: structs) {
    ++i;
    for (auto field: fields) {
    mxSetField(result, i, field, mxGetField(scalarStruct, 0, field));
    }
    }
    return result;
    }
    } // namespace maoxdb
    ......@@ -6,6 +6,7 @@
    #include "caosdb/transaction.h"
    #include "caosdb/transaction_status.h"
    #include "mex.h"
    #include <boost/algorithm/string.hpp>
    #include <string>
    /**
    ......@@ -38,7 +39,9 @@
    * - value
    * - unit
    * - datatype
    * - errors: Array of messages (struct of code and description).
    * - errors: Struct array with the following fields:
    * - code (as INT64)
    * - description
    * - warnings: Like messages.
    * - infos: Like messages.
    *
    ......@@ -79,21 +82,45 @@ inline auto mxEmptyDOUBLE() -> mxArray * {
    }
    /**
    * @brief Convert the string-typed value in an Entity-like object to a mxArray,
    * @brief Convert the string-typed value in an Entity-like object to a mxArray.
    *
    * @details For the existing datatypes, see https://docs.indiscale.com/caosdb-server/specification/Datatype.html
    */
    template <class T>
    auto mxScalarFromStringValue(const T& entity) -> mxArray * {
    mxArray * result = nullptr;
    mxArray * result;
    auto dt = entity.GetDatatype();
    auto value = entity.GetValue();
    std::cout << "Datatype/Value: " << dt << ": " << value << std::endl;
    if (dt.empty()) {
    result = mxEmptyDOUBLE();
    } else if (dt == "TEXT") {
    result = mxCreateString(value.c_str());
    } else if (dt == "BOOLEAN") {
    if (boost::to_upper_copy(value) == "TRUE") {
    result = mxScalarLOGICAL(1);
    } else {
    mxAssert(boost::to_upper_copy(value) == "FALSE",
    std::string("Value >") + value + "< is neither FALSE nor TRUE.");
    result = mxScalarLOGICAL(0);
    }
    } else if (dt == "INTEGER") {
    result = mxScalarINT64(stol(entity.GetValue()));
    result = mxScalarINT64(stol(value));
    } else if (dt == "DOUBLE") {
    result = mxScalarDOUBLE(stol(entity.GetValue()));
    result = mxScalarDOUBLE(stol(value));
    } else if (dt == "FILE") {
    result = mxCreateString(value.c_str());
    } else if (dt == "REFERENCE") {
    result = mxCreateString(value.c_str());
    } else if (dt == "DATETIME") {
    result = mxCreateString(value.c_str());
    } else if (dt.substr(0, 4) == "LIST") {
    mexErrMsgTxt("List values are not implemented yet.");
    } else {
    std::cerr << "Unknown datatype: " << dt << "." << std::endl;
    std::cout << "Unknown datatype, probably a reference: " << dt << ": " << value << std::endl;
    result = mxCreateString(value.c_str());
    }
    mxAssert(result, "Scalar value must have some result now.");
    return result;
    }
    ......@@ -162,14 +189,31 @@ void throwOctException(const caosdb::exceptions::Exception &exc);
    /**
    * @brief Convert a ResultSet to a struct mexArray.
    *
    * @return A 1xN struct array, with Entity structs as values.
    */
    auto mxFromResultSet(const caosdb::transaction::ResultSet &resultSet) -> mxArray *;
    /**
    * @brief Convert an Entity from libcaosdb to Octave struct mexArray.
    *
    * @return A 1x1 struct array whose entry follows the maoxdb Entity convention outlined above.
    */
    auto mxFromCaosDBEntity(const caosdb::entity::Entity &entity) -> mxArray *;
    // Utility functions //////////////////////////////////////////////////////////
    /**
    * @brief Merges a number of scalar mex structs into a 1xN struct.
    *
    * @details No content is duplicated, the mxArray pointers of the input structs values are reused.
    *
    * @param structs: Must all have the same fields.
    *
    * @return A 1xN struct array.
    */
    auto mxMergeScalarStructs(const std::vector<const mxArray *> &structs) -> mxArray*;
    } // namespace maoxdb
    #endif /* MAOXDB_H */
    ......@@ -106,7 +106,8 @@ void mexFunction(int /*nlhs*/, mxArray *plhs[], int nrhs,
    auto *mxResults = maoxdb::mxFromResultSet(results);
    plhs[0] = mxDuplicateArray(prhs[0]);
    std::cout << "mxResults" << std::endl;
    plhs[0] = mxDuplicateArray(mxResults);
    // plhs[1] = mxDuplicateArray (prhs[1]);
    // auto *info_struct = info(conn_name);
    // plhs[0] = info_struct;
    ......
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment