C++ 示例: CurlSource

使用 CurlSource 示例,您可以使用 cURL 通过 HTTP 打开和读入文件。该示例作为以下内容的一部分提供:/opt/vertica/sdk/examples/SourceFunctions/cURL.cpp

源代码实施

此示例使用位于 /opt/vertica/sdk/examples/HelperLibraries/ 中的 helper 库。

CurlSource 按区块加载数据。如果解析器遇到 EndOfFile 标记,则 process() 方法将返回 DONE。否则,该方法将返回 OUTPUT_NEEDED 并处理其他数据区块。helper 库中包含的函数(例如 url_fread()url_fopen())基于随 libcurl 库附带提供的示例。有关示例,请访问 http://curl.haxx.se/libcurl/c/fopen.html

setup() 函数可打开文件句柄,而 destroy() 函数可关闭文件句柄。它们都使用 helper 库中的函数。

class CurlSource : public UDSource {private:
    URL_FILE *handle;
    std::string url;
    virtual StreamState process(ServerInterface &srvInterface, DataBuffer &output) {
        output.offset = url_fread(output.buf, 1, output.size, handle);
        return url_feof(handle) ? DONE : OUTPUT_NEEDED;
    }
public:
    CurlSource(std::string url) : url(url) {}
    void setup(ServerInterface &srvInterface) {
        handle = url_fopen(url.c_str(),"r");
    }
    void destroy(ServerInterface &srvInterface) {
        url_fclose(handle);
    }
};

工厂实施

CurlSourceFactory 可生成 CurlSource 实例。

class CurlSourceFactory : public SourceFactory {public:
    virtual void plan(ServerInterface &srvInterface,
            NodeSpecifyingPlanContext &planCtxt) {
        std::vector<std::string> args = srvInterface.getParamReader().getParamNames();
       /* Check parameters */
        if (args.size() != 1 || find(args.begin(), args.end(), "url") == args.end()) {
            vt_report_error(0, "You must provide a single URL.");
        }
        /* Populate planData */
        planCtxt.getWriter().getStringRef("url").copy(
                                    srvInterface.getParamReader().getStringRef("url"));

        /* Assign Nodes */
        std::vector<std::string> executionNodes = planCtxt.getClusterNodes();
        while (executionNodes.size() > 1) executionNodes.pop_back();
        // Only run on the first node in the list.
        planCtxt.setTargetNodes(executionNodes);
    }
    virtual std::vector<UDSource*> prepareUDSources(ServerInterface &srvInterface,
            NodeSpecifyingPlanContext &planCtxt) {
        std::vector<UDSource*> retVal;
        retVal.push_back(vt_createFuncObj(srvInterface.allocator, CurlSource,
                planCtxt.getReader().getStringRef("url").str()));
        return retVal;
    }
    virtual void getParameterType(ServerInterface &srvInterface,
                                  SizedColumnTypes &parameterTypes) {
        parameterTypes.addVarchar(65000, "url");
    }
};
RegisterFactory(CurlSourceFactory);