diff options
author | Ted Tuckman <ted.tuckman@mongodb.com> | 2017-06-20 11:54:53 -0400 |
---|---|---|
committer | Ted Tuckman <ted.tuckman@mongodb.com> | 2017-06-23 13:22:45 -0400 |
commit | 7f0caad1b2e62bd8a1533f865fab220c8e853464 (patch) | |
tree | 15179a8dae06b368e8947c40c1e2aeda1ee14d2d | |
parent | cf713d9b8cf0436f08facc8171ffb407d380ea85 (diff) | |
download | mongo-7f0caad1b2e62bd8a1533f865fab220c8e853464.tar.gz |
SERVER-29717 Add barebones mongodbcapi
-rw-r--r-- | src/mongo/client/SConscript | 10 | ||||
-rw-r--r-- | src/mongo/client/embedded/SConscript | 16 | ||||
-rw-r--r-- | src/mongo/client/embedded/libmongodbcapi.cpp | 150 | ||||
-rw-r--r-- | src/mongo/client/embedded/libmongodbcapi.h | 130 |
4 files changed, 306 insertions, 0 deletions
diff --git a/src/mongo/client/SConscript b/src/mongo/client/SConscript index d86fd987d1d..3d478ee246c 100644 --- a/src/mongo/client/SConscript +++ b/src/mongo/client/SConscript @@ -4,6 +4,16 @@ Import('env') env = env.Clone() + +env.SConscript( + dirs=[ + 'embedded', + ], + exports=[ + 'env', + ], +) + # Contains only the core ConnectionString functionality, *not* the ability to call connect() # and return a DBClientBase* back. For that you need to link against the 'clientdriver' library. env.Library( diff --git a/src/mongo/client/embedded/SConscript b/src/mongo/client/embedded/SConscript new file mode 100644 index 00000000000..b4c435c09b0 --- /dev/null +++ b/src/mongo/client/embedded/SConscript @@ -0,0 +1,16 @@ +# -*- mode: python; -*- + +Import("env") + +env = env.Clone() + +capi = env.Library( + target='mongo_embedded_capi', + source=[ + 'libmongodbcapi.cpp', + ], + LIBDEPS=[] +) + +env.Alias( 'embedded_capi', capi) + diff --git a/src/mongo/client/embedded/libmongodbcapi.cpp b/src/mongo/client/embedded/libmongodbcapi.cpp new file mode 100644 index 00000000000..45e0d6a7913 --- /dev/null +++ b/src/mongo/client/embedded/libmongodbcapi.cpp @@ -0,0 +1,150 @@ +/** + * Copyright (C) 2017 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects + * for all of the code used other than as permitted herein. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you do not + * wish to do so, delete this exception statement from your version. If you + * delete this exception statement from all source files in the program, + * then also delete it in the license file. + */ + +#include "mongo/client/embedded/libmongodbcapi.h" + +#include <exception> +#include <unordered_map> +#include <vector> + +#include "mongo/stdx/memory.h" +#include "mongo/stdx/unordered_map.h" +#include "mongo/util/assert_util.h" + +struct libmongodbcapi_db { + libmongodbcapi_db() = default; + + libmongodbcapi_db(const libmongodbcapi_db&) = delete; + libmongodbcapi_db& operator=(const libmongodbcapi_db&) = delete; + + void* db_sc = nullptr; + mongo::stdx::unordered_map<libmongodbcapi_client*, std::unique_ptr<libmongodbcapi_client>> + open_clients; +}; +struct libmongodbcapi_client { + libmongodbcapi_client(libmongodbcapi_db* db) : parent_db(db) {} + + libmongodbcapi_client(const libmongodbcapi_client&) = delete; + libmongodbcapi_client& operator=(const libmongodbcapi_client&) = delete; + + void* client_handle = nullptr; + std::vector<unsigned char> output; + libmongodbcapi_db* parent_db = nullptr; +}; + +namespace mongo { +namespace { + +libmongodbcapi_db* global_db = nullptr; +thread_local int last_error = LIBMONGODB_CAPI_ERROR_SUCCESS; + +libmongodbcapi_db* db_new(int argc, const char** argv, const char** envp) noexcept try { + last_error = LIBMONGODB_CAPI_ERROR_SUCCESS; + if (global_db) { + throw std::runtime_error("DB already exists"); + } + global_db = new libmongodbcapi_db; + return global_db; +} catch (const std::exception& e) { + last_error = LIBMONGODB_CAPI_ERROR_UNKNOWN; + return nullptr; +} + +void db_destroy(libmongodbcapi_db* db) noexcept { + delete db; + invariant(!db || db == global_db); + if (db) { + global_db = nullptr; + } +} + +int db_pump(libmongodbcapi_db* db) noexcept try { + return LIBMONGODB_CAPI_ERROR_SUCCESS; +} catch (const std::exception& e) { + return LIBMONGODB_CAPI_ERROR_UNKNOWN; +} + +libmongodbcapi_client* client_new(libmongodbcapi_db* db) noexcept try { + auto new_client = stdx::make_unique<libmongodbcapi_client>(db); + libmongodbcapi_client* rv = new_client.get(); + db->open_clients.insert(std::make_pair(rv, std::move(new_client))); + return rv; +} catch (const std::exception& e) { + return nullptr; +} + +void client_destroy(libmongodbcapi_client* client) noexcept { + if (!client) { + return; + } + client->parent_db->open_clients.erase(client); +} + +int client_wire_protocol_rpc(libmongodbcapi_client* client, + const void* input, + size_t input_size, + void** output, + size_t* output_size) noexcept { + return LIBMONGODB_CAPI_ERROR_SUCCESS; +} + +int get_last_error() noexcept { + return last_error; +} +} // namespace +} // namespace mongo + +extern "C" { +libmongodbcapi_db* libmongodbcapi_db_new(int argc, const char** argv, const char** envp) { + return mongo::db_new(argc, argv, envp); +} + +void libmongodbcapi_db_destroy(libmongodbcapi_db* db) { + return mongo::db_destroy(db); +} + +int libmongodbcapi_db_pump(libmongodbcapi_db* p) { + return mongo::db_pump(p); +} + +libmongodbcapi_client* libmongdbcapi_db_client_new(libmongodbcapi_db* db) { + return mongo::client_new(db); +} + +void libmongdbcapi_db_client_destroy(libmongodbcapi_client* client) { + return mongo::client_destroy(client); +} + +int libmongdbcapi_db_client_wire_protocol_rpc(libmongodbcapi_client* client, + const void* input, + size_t input_size, + void** output, + size_t* output_size) { + return mongo::client_wire_protocol_rpc(client, input, input_size, output, output_size); +} +} diff --git a/src/mongo/client/embedded/libmongodbcapi.h b/src/mongo/client/embedded/libmongodbcapi.h new file mode 100644 index 00000000000..2463bc784a7 --- /dev/null +++ b/src/mongo/client/embedded/libmongodbcapi.h @@ -0,0 +1,130 @@ +/** + * Copyright (C) 2017 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects + * for all of the code used other than as permitted herein. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you do not + * wish to do so, delete this exception statement from your version. If you + * delete this exception statement from all source files in the program, + * then also delete it in the license file. + */ +#ifndef LIBMONGODBCAPI_H +#define LIBMONGODBCAPI_H + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct libmongodbcapi_db libmongodbcapi_db; +typedef struct libmongodbcapi_client libmongodbcapi_client; + +typedef enum { + LIBMONGODB_CAPI_ERROR_UNKNOWN = -1, + LIBMONGODB_CAPI_ERROR_SUCCESS +} libmongodbcapi_error; + +/** +* Starts the database and returns a handle with the service context. +* +* @param argc +* The number of arguments in argv +* @param argv +* The arguments that will be passed to mongod at startup to initialize state +* @param envp +* Environment variables that will be passed to mongod at startup to initilize state +* +* @return A pointer to a db handle or null on error +*/ +libmongodbcapi_db* libmongodbcapi_db_new(int argc, const char** argv, const char** envp); + +/** +* Shuts down the database +* +* @param +* A pointer to a db handle to be destroyed +*/ +void libmongodbcapi_db_destroy(libmongodbcapi_db* db); + +/** +* Let the database do background work. Returns an int from the error enum +* +* @param +* The database that has work that needs to be done +* +* @return A libmongo error code +*/ +int libmongodbcapi_db_pump(libmongodbcapi_db* db); + +/** +* Creates a new clienst and retuns it so the caller can do operation +* A client will be destroyed when the owning db is destroyed +* +* @param db +* The datadase that will own this client and execute its RPC calls +* +* @return A pointer to a client or null on error +*/ +libmongodbcapi_client* libmongodbcapi_db_client_new(libmongodbcapi_db* db); + +/** +* Destroys a client and removes it from the db/service context +* Cannot be called after the owning db is destroyed +* +* @param client +* A pointer to the client to be destroyed +*/ +void libmongodbcapi_db_client_destroy(libmongodbcapi_client* client); + +/** +* Makes an RPC call to the database +* +* @param client +* The client that will be performing the query on the database +* @param input +* The query to be sent to and then executed by the database +* @param input_size +* The size (number of bytes) of the input query +* @param output +* A pointer to a void * where the database can write the location of the output. +* The library will manage the memory pointer to by *output. +* @TODO document lifetime of this buffer +* @param output_size +* A pointer to a location where this function will write the size (number of bytes) +* of the output +* +* @return A success or error code +*/ +int libmongodbcapi_db_client_wire_protocol_rpc(libmongodbcapi_client* client, + const void* input, + size_t input_size, + void** output, + size_t* output_size); +/** +* @return a per-thread value indicating the last error +*/ +int libmongodbcapi_get_last_error(); + +#ifdef __cplusplus +} +#endif + +#endif |