summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Tuckman <ted.tuckman@mongodb.com>2017-06-20 11:54:53 -0400
committerTed Tuckman <ted.tuckman@mongodb.com>2017-06-23 13:22:45 -0400
commit7f0caad1b2e62bd8a1533f865fab220c8e853464 (patch)
tree15179a8dae06b368e8947c40c1e2aeda1ee14d2d
parentcf713d9b8cf0436f08facc8171ffb407d380ea85 (diff)
downloadmongo-7f0caad1b2e62bd8a1533f865fab220c8e853464.tar.gz
SERVER-29717 Add barebones mongodbcapi
-rw-r--r--src/mongo/client/SConscript10
-rw-r--r--src/mongo/client/embedded/SConscript16
-rw-r--r--src/mongo/client/embedded/libmongodbcapi.cpp150
-rw-r--r--src/mongo/client/embedded/libmongodbcapi.h130
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