From 0058ee5b929ed8dc7f9035c31ae55d9b8619cdda Mon Sep 17 00:00:00 2001 From: Diego Freniche Date: Mon, 13 Mar 2023 19:18:44 +0100 Subject: [PATCH] Added code and README --- README.md | 19 +++++++++ bcon.c | 73 ++++++++++++++++++++++++++++++++ build-all.sh | 30 +++++++++++++ delete.c | 103 +++++++++++++++++++++++++++++++++++++++++++++ find.c | 87 ++++++++++++++++++++++++++++++++++++++ hello_mongoc.c | 95 +++++++++++++++++++++++++++++++++++++++++ insert.c | 89 +++++++++++++++++++++++++++++++++++++++ list_collections.c | 78 ++++++++++++++++++++++++++++++++++ 8 files changed, 574 insertions(+) create mode 100644 README.md create mode 100644 bcon.c create mode 100755 build-all.sh create mode 100644 delete.c create mode 100644 find.c create mode 100644 hello_mongoc.c create mode 100644 insert.c create mode 100644 list_collections.c diff --git a/README.md b/README.md new file mode 100644 index 0000000..91d40ad --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# Hello, MongoC + +Some simple examples using the [MongoDB C driver](https://www.mongodb.com/docs/drivers/c/) + +## Build and run + +These examples are built using GCC on macOS, but they should compile anywhere that has a C compiler + +- clone this repo +- create a file called `URI.h` that contains your MongoDB Connection String, with this content: +```c +// URI.h +#define MY_MONGODB_URI "mongodb+srv://" +``` + +- Make the build script executable `chmod a+x build-all.sh` +- `./build-all.sh` + +In macOS you need to install Xcode first (free on the Mac App Store) \ No newline at end of file diff --git a/bcon.c b/bcon.c new file mode 100644 index 0000000..fcdf368 --- /dev/null +++ b/bcon.c @@ -0,0 +1,73 @@ +// bcon.c +// https://mongoc.org/libmongoc/current/tutorial.html#using-bcon +#include + +// Creating the JSON doc: +/* +{ + born : ISODate("1906-12-09"), + died : ISODate("1992-01-01"), + name : { + first : "Grace", + last : "Hopper" + }, + languages : [ "MATH-MATIC", "FLOW-MATIC", "COBOL" ], + degrees: [ { degree: "BA", school: "Vassar" }, + { degree: "PhD", school: "Yale" } ] +} +*/ + +int main(int argc, char *argv[]) { + struct tm born = {0}; + struct tm died = {0}; + bson_t *document; + char *str; + + born.tm_year = 6; + born.tm_mon = 11; + born.tm_mday = 9; + + died.tm_year = 92; + died.tm_mon = 0; + died.tm_mday = 1; + + // document = BCON_NEW("born", BCON_DATE_TIME(mktime(&born) * 1000), + // "died", BCON_DATE_TIME(mktime(&died) * 1000), + // "name", "{", + // "first", BCON_UTF8("Grace"), + // "last", BCON_UTF8("Hopper"), + // "}", + // "languages", "[", + // BCON_UTF8("MATH-MATIC"), + // BCON_UTF8("FLOW-MATIC"), + // BCON_UTF8("COBOL"), + // "]", + // "degrees", "[", + // "{", "degree", BCON_UTF8("BA"), "school", + // BCON_UTF8("Vassar"), "}", + // "{", "degree", BCON_UTF8("PhD"),"school", + // BCON_UTF8("Yale"), "}", + // "]"); + + document = BCON_NEW("born", BCON_DATE_TIME(mktime(&born) * 1000), "died", + BCON_DATE_TIME(mktime(&died) * 1000), "name", "{", + "first", BCON_UTF8("Grace"), "last", BCON_UTF8("Hopper"), + "}", "languages", "[", BCON_UTF8("MATH-MATIC"), + BCON_UTF8("FLOW-MATIC"), BCON_UTF8("COBOL"), "]", + "degrees", "[", "{", "degree", BCON_UTF8("BA"), "school", + BCON_UTF8("Vassar"), "}", "{", "degree", BCON_UTF8("PhD"), + "school", BCON_UTF8("Yale"), "}", "]"); + + /* + * Print the document as a JSON string. + */ + str = bson_as_canonical_extended_json(document, NULL); + printf("%s\n", str); + bson_free(str); + + /* + * Clean up allocated bson documents. + */ + bson_destroy(document); + return 0; +} \ No newline at end of file diff --git a/build-all.sh b/build-all.sh new file mode 100755 index 0000000..701c329 --- /dev/null +++ b/build-all.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +SOURCE_FILES="insert find bcon list_collections hello_mongoc delete" + +mkdir output + +echo COMPILING ALL EXAMPLES! + +for file in $SOURCE_FILES +do + +echo "Compiling $file" + +gcc -o output/$file $file.c \ + -I/usr/local/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 \ + -lmongoc-1.0 -lbson-1.0 -Wdeprecated-declarations -w + +done + +echo RUNNING ALL EXAMPLES! 🚀 + +for file in $SOURCE_FILES +do + +echo "Running $file" +echo "-------------" + +./output/$file + +done \ No newline at end of file diff --git a/delete.c b/delete.c new file mode 100644 index 0000000..b2849b6 --- /dev/null +++ b/delete.c @@ -0,0 +1,103 @@ +// delete.c +#include "URI.h" +#include + +int main(int argc, char const *argv[]) { + // your MongoDB URI connection string + const char *uri_string = MY_MONGODB_URI; + // MongoDB URI created from above string + mongoc_uri_t *uri; + // MongoDB Client, used to connect to the DB + mongoc_client_t *client; + + // Error management + bson_error_t error; + + mongoc_collection_t *collection; + char **collection_names; + unsigned i; + + // Object id and BSON doc + bson_oid_t oid; + bson_t *doc; + + char *str; + + /* + * Required to initialize libmongoc's internals + */ + mongoc_init(); + + /* + * Safely create a MongoDB URI object from the given string + */ + uri = mongoc_uri_new_with_error(uri_string, &error); + if (!uri) { + fprintf(stderr, + "failed to parse URI: %s\n" + "error message: %s\n", + uri_string, error.message); + return EXIT_FAILURE; + } + + /* + * Create a new client instance, here we use the uri we just built + */ + client = mongoc_client_new_from_uri(uri); + if (!client) { + return EXIT_FAILURE; + } + + /* + * Register the application name so we can track it in the profile logs + * on the server. This can also be done from the URI (see other examples). + */ + mongoc_client_set_appname(client, "connect-example"); + + /* + * Get a handle on the database "db_name" and collection "coll_name" + */ + collection = mongoc_client_get_collection(client, "sample_mflix", "movies"); + + // Let's insert one document in this collection! + doc = bson_new(); + bson_oid_init(&oid, NULL); + BSON_APPEND_OID(doc, "_id", &oid); + BSON_APPEND_UTF8(doc, "name", "My super new picture"); + + if (!mongoc_collection_insert_one(collection, doc, NULL, NULL, &error)) { + fprintf(stderr, "%s\n", error.message); + } else { + printf("Document inserted!"); + /* + * Print the document as a JSON string. + */ + str = bson_as_canonical_extended_json(doc, NULL); + printf("%s\n", str); + bson_free(str); + } + + bson_destroy(doc); + + // Delete the inserted document! + + doc = bson_new(); + BSON_APPEND_OID(doc, "_id", &oid); + + if (!mongoc_collection_delete_one(collection, doc, NULL, NULL, &error)) { + fprintf(stderr, "Delete failed: %s\n", error.message); + } else { + puts("Document deleted!"); + } + + /* + * Release our handles and clean up libmongoc + */ + + mongoc_collection_destroy(collection); + mongoc_uri_destroy(uri); + mongoc_client_destroy(client); + mongoc_cleanup(); + + return EXIT_SUCCESS; +} diff --git a/find.c b/find.c new file mode 100644 index 0000000..4747b7a --- /dev/null +++ b/find.c @@ -0,0 +1,87 @@ +// find.c +#include "URI.h" +#include + +int main(int argc, char const *argv[]) { + // your MongoDB URI connection string + const char *uri_string = MY_MONGODB_URI; + // MongoDB URI created from above string + mongoc_uri_t *uri; + // MongoDB Client, used to connect to the DB + mongoc_client_t *client; + + // Error management + bson_error_t error; + + mongoc_collection_t *collection; + char **collection_names; + unsigned i; + + // Query object + bson_t *query; + mongoc_cursor_t *cursor; + + char *str; + + /* + * Required to initialize libmongoc's internals + */ + mongoc_init(); + + /* + * Safely create a MongoDB URI object from the given string + */ + uri = mongoc_uri_new_with_error(uri_string, &error); + if (!uri) { + fprintf(stderr, + "failed to parse URI: %s\n" + "error message: %s\n", + uri_string, error.message); + return EXIT_FAILURE; + } + + /* + * Create a new client instance, here we use the uri we just built + */ + client = mongoc_client_new_from_uri(uri); + if (!client) { + puts("Error connecting!"); + return EXIT_FAILURE; + } + + /* + * Register the application name so we can track it in the profile logs + * on the server. This can also be done from the URI (see other examples). + */ + mongoc_client_set_appname(client, "connect-example"); + + /* + * Get a handle on the database "db_name" and collection "coll_name" + */ + collection = mongoc_client_get_collection(client, "sample_mflix", "movies"); + + query = bson_new(); + + // All movies from 1984! + BSON_APPEND_INT32(query, "year", 1984); + cursor = mongoc_collection_find_with_opts(collection, query, NULL, NULL); + + while (mongoc_cursor_next(cursor, &query)) { + str = bson_as_canonical_extended_json(query, NULL); + printf("%s\n", str); + bson_free(str); + } + + /* + * Release our handles and clean up libmongoc + */ + + bson_destroy(query); + + mongoc_collection_destroy(collection); + mongoc_uri_destroy(uri); + mongoc_client_destroy(client); + mongoc_cleanup(); + + return EXIT_SUCCESS; +} diff --git a/hello_mongoc.c b/hello_mongoc.c new file mode 100644 index 0000000..dea2e06 --- /dev/null +++ b/hello_mongoc.c @@ -0,0 +1,95 @@ +#include "URI.h" +#include + +int main(int argc, char const *argv[]) { + // your MongoDB URI connection string + const char *uri_string = MY_MONGODB_URI; + // MongoDB URI created from above string + mongoc_uri_t *uri; + // MongoDB Client, used to connect to the DB + mongoc_client_t *client; + // Command to be sent, and reply + bson_t *command, reply; + // Error management + bson_error_t error; + // Misc + char *str; + bool retval; + + /* + * Required to initialize libmongoc's internals + */ + mongoc_init(); + + /* + * Optionally get MongoDB URI from command line + */ + if (argc > 1) { + uri_string = argv[1]; + } + + /* + * Safely create a MongoDB URI object from the given string + */ + uri = mongoc_uri_new_with_error(uri_string, &error); + if (!uri) { + fprintf(stderr, + "failed to parse URI: %s\n" + "error message: %s\n", + uri_string, error.message); + return EXIT_FAILURE; + } + + /* + * Create a new client instance, here we use the uri we just built + */ + client = mongoc_client_new_from_uri(uri); + if (!client) { + return EXIT_FAILURE; + } + + /* + * Register the application name so we can track it in the profile logs + * on the server. This can also be done from the URI (see other examples). + */ + mongoc_client_set_appname(client, "connect-example"); + + /* + * Do work. This example pings the database and prints the result as JSON + * BCON == BSON C Object Notation + */ + command = BCON_NEW("ping", BCON_INT32(1)); + + // we run above command on our DB, using the client. We get reply and error + // (if any) + retval = mongoc_client_command_simple(client, "admin", command, NULL, &reply, + &error); + + // mongoc_client_command_simple returns false and sets error if there are + // invalid arguments or a server or network error. + if (!retval) { + fprintf(stderr, "%s\n", error.message); + return EXIT_FAILURE; + } + + // if we're here, there's a JSON response + str = bson_as_json(&reply, NULL); + printf("%s\n", str); + + /* + * Clean up memory + */ + bson_destroy(&reply); + bson_destroy(command); + bson_free(str); + + /* + * Release our handles and clean up libmongoc + */ + + mongoc_uri_destroy(uri); + mongoc_client_destroy(client); + mongoc_cleanup(); + + return EXIT_SUCCESS; +} diff --git a/insert.c b/insert.c new file mode 100644 index 0000000..d0adc24 --- /dev/null +++ b/insert.c @@ -0,0 +1,89 @@ +// insert.c +#include "URI.h" +#include + +int main(int argc, char const *argv[]) { + // your MongoDB URI connection string + const char *uri_string = MY_MONGODB_URI; + // MongoDB URI created from above string + mongoc_uri_t *uri; + // MongoDB Client, used to connect to the DB + mongoc_client_t *client; + + // Error management + bson_error_t error; + + mongoc_collection_t *collection; + char **collection_names; + unsigned i; + + // Object id and BSON doc + bson_oid_t oid; + bson_t *doc; + + char *str; + + /* + * Required to initialize libmongoc's internals + */ + mongoc_init(); + + /* + * Safely create a MongoDB URI object from the given string + */ + uri = mongoc_uri_new_with_error(uri_string, &error); + if (!uri) { + fprintf(stderr, + "failed to parse URI: %s\n" + "error message: %s\n", + uri_string, error.message); + return EXIT_FAILURE; + } + + /* + * Create a new client instance, here we use the uri we just built + */ + client = mongoc_client_new_from_uri(uri); + if (!client) { + return EXIT_FAILURE; + } + + /* + * Register the application name so we can track it in the profile logs + * on the server. This can also be done from the URI (see other examples). + */ + mongoc_client_set_appname(client, "connect-example"); + + /* + * Get a handle on the database "db_name" and collection "coll_name" + */ + collection = mongoc_client_get_collection(client, "sample_mflix", "movies"); + + doc = bson_new(); + bson_oid_init(&oid, NULL); + BSON_APPEND_OID(doc, "_id", &oid); + BSON_APPEND_UTF8(doc, "name", "My super new picture"); + + if (!mongoc_collection_insert_one(collection, doc, NULL, NULL, &error)) { + fprintf(stderr, "%s\n", error.message); + } else { + printf("Document inserted!"); + /* + * Print the document as a JSON string. + */ + str = bson_as_canonical_extended_json(doc, NULL); + printf("%s\n", str); + bson_free(str); + } + + /* + * Release our handles and clean up libmongoc + */ + + mongoc_collection_destroy(collection); + mongoc_uri_destroy(uri); + mongoc_client_destroy(client); + mongoc_cleanup(); + + return EXIT_SUCCESS; +} diff --git a/list_collections.c b/list_collections.c new file mode 100644 index 0000000..93f1128 --- /dev/null +++ b/list_collections.c @@ -0,0 +1,78 @@ +// list_collections.c +#include "URI.h" +#include + +int main(int argc, char const *argv[]) { + // your MongoDB URI connection string + const char *uri_string = MY_MONGODB_URI; + // MongoDB URI created from above string + mongoc_uri_t *uri; + // MongoDB Client, used to connect to the DB + mongoc_client_t *client; + + // Error management + bson_error_t error; + + mongoc_database_t *database; + mongoc_collection_t *collection; + char **collection_names; + unsigned i; + + /* + * Required to initialize libmongoc's internals + */ + mongoc_init(); + + /* + * Safely create a MongoDB URI object from the given string + */ + uri = mongoc_uri_new_with_error(uri_string, &error); + if (!uri) { + fprintf(stderr, + "failed to parse URI: %s\n" + "error message: %s\n", + uri_string, error.message); + return EXIT_FAILURE; + } + + /* + * Create a new client instance, here we use the uri we just built + */ + client = mongoc_client_new_from_uri(uri); + if (!client) { + return EXIT_FAILURE; + } + + /* + * Register the application name so we can track it in the profile logs + * on the server. This can also be done from the URI (see other examples). + */ + mongoc_client_set_appname(client, "connect-example"); + + /* + * Get a handle on the database "db_name" and collection "coll_name" + */ + database = mongoc_client_get_database(client, "sample_mflix"); + + if ((collection_names = + mongoc_database_get_collection_names(database, &error))) { + for (i = 0; collection_names[i]; i++) { + printf("%s\n", collection_names[i]); + } + + } else { + fprintf(stderr, "Error: %s\n", error.message); + return EXIT_FAILURE; + } + + /* + * Release our handles and clean up libmongoc + */ + + mongoc_database_destroy(database); + mongoc_uri_destroy(uri); + mongoc_client_destroy(client); + mongoc_cleanup(); + + return EXIT_SUCCESS; +}