From ceb757bc832e615edb2257daeda443e1d5138bdc Mon Sep 17 00:00:00 2001 From: ActionBot Date: Fri, 7 Jun 2024 16:35:53 +0000 Subject: [PATCH 001/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 1a66121..be76887 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -1551a396951d0a745947e9d6e449f79f7c08d306 +7ce9bfde97b1b1ab74431247ebd42a00d575eb8d From 99df9d23e793387e1d0e6677a1487d7c90265d6d Mon Sep 17 00:00:00 2001 From: jwongmongodb <116834447+jwongmongodb@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:12:54 -0400 Subject: [PATCH 002/230] BAAS-30358: add node-fetch third party dependency (#42) * add manifest validator action; does not yet check root-level * testing jq instaltion; changing others to pull_request only * force run on jqtest * add further testing * got file checking working. updated manifest file to fail * reset manifest file; clean up actions * fix validate_files action * disable onbe action to focus on fixing the other * trying to get head branch of PR * forgot to specify repo * try base ref and rebase * back to pull source branch; re-added no-edit and amend * gigit not a valid command. who knew? * back to main; else get detached state * pulling from main leads to merge conflict; resorting to -force * same errror * getting sloppy * add HEAD: * remove function name prefix * BAAS-30359: add axios third party snippets * shorten axios description * use better test endpoint * Fixing github actions causing detached head issue (#41) Fix remaining github action issues * update commit hash * update commit hash * BAAS-30358: add note-fetch third party dependency * update commit hash * remove function name prefix * update commit hash --------- Co-authored-by: MongoCaleb Co-authored-by: MongoCaleb <32645888+MongoCaleb@users.noreply.github.com> --- .../workflows/Remove-Function-Name-Prefix.yml | 3 +-- latestCommit.md | 2 +- snippets/functions/func.js | 0 snippets/functions/third-party/axios.js | 10 ++++++++++ snippets/functions/third-party/manifest.json | 16 ++++++++++++++-- snippets/functions/third-party/nodeFetch.js | 9 +++++++++ 6 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 snippets/functions/func.js create mode 100644 snippets/functions/third-party/axios.js create mode 100644 snippets/functions/third-party/nodeFetch.js diff --git a/.github/workflows/Remove-Function-Name-Prefix.yml b/.github/workflows/Remove-Function-Name-Prefix.yml index 0265894..068ddb0 100644 --- a/.github/workflows/Remove-Function-Name-Prefix.yml +++ b/.github/workflows/Remove-Function-Name-Prefix.yml @@ -28,5 +28,4 @@ jobs: git commit -m 'remove function name prefix' git push origin ${{ github.ref }} fi - - echo "done" \ No newline at end of file + echo "done" diff --git a/latestCommit.md b/latestCommit.md index be76887..3fa7583 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -7ce9bfde97b1b1ab74431247ebd42a00d575eb8d +fa5299850924cbfcb2296e02ead457e7cbc2ea0f diff --git a/snippets/functions/func.js b/snippets/functions/func.js new file mode 100644 index 0000000..e69de29 diff --git a/snippets/functions/third-party/axios.js b/snippets/functions/third-party/axios.js new file mode 100644 index 0000000..5f6ce08 --- /dev/null +++ b/snippets/functions/third-party/axios.js @@ -0,0 +1,10 @@ +exports = async function () { + const axios = require("axios").default; + const response = await axios.get( + "https://jsonplaceholder.typicode.com/posts/2", + { + headers: { "Content-Type": "application/json" }, + } + ); + return response.data.userId; +}; diff --git a/snippets/functions/third-party/manifest.json b/snippets/functions/third-party/manifest.json index 5c6555a..ec935ec 100644 --- a/snippets/functions/third-party/manifest.json +++ b/snippets/functions/third-party/manifest.json @@ -5,9 +5,21 @@ "snippets": [ { "id": "e5450427-8503-4e1a-aac3-03e5e39e8f8e", - "title": "Calling Twilio service via NPM dependency", + "title": "Calling Twilio service", "snippet": "/twilio.js", "description": "Calling the Twilio service with the official Twilio Node Helper Library. To authenticate Twilio requests, store your Account SID and Auth Token as values. You can then access them within functions and pass them to the SDK." + }, + { + "id": "b1b777e1-0747-46dc-bf4e-0f3ddb7244cd", + "title": "Using axios dependency", + "snippet": "/axios.js", + "description": "Making HTTP requests with axios npm dependency." + }, + { + "id": "3c0e06b6-313e-4321-8794-47b53d66e961", + "title": "Using node-fetch dependency", + "snippet": "/nodeFetch.js", + "description": "Making HTTP requests with node-fetch dependency. Atlas App Services does not support v3 of node-fetch, use v2 instead." } ] -} \ No newline at end of file +} diff --git a/snippets/functions/third-party/nodeFetch.js b/snippets/functions/third-party/nodeFetch.js new file mode 100644 index 0000000..001abb9 --- /dev/null +++ b/snippets/functions/third-party/nodeFetch.js @@ -0,0 +1,9 @@ +exports = async function () { + const fetch = require("node-fetch"); // require calls must be in exports function + const response = await fetch("https://jsonplaceholder.typicode.com/posts/2", { + method: "GET", + headers: { "Content-Type": "application/json" }, + }); + const result = await response.json(); + return result.userId; +}; From 1170e53bac8220db6f9f839fb3b511b562095cdc Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 10 Jun 2024 19:13:07 +0000 Subject: [PATCH 003/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 3fa7583..decd721 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -fa5299850924cbfcb2296e02ead457e7cbc2ea0f +99df9d23e793387e1d0e6677a1487d7c90265d6d From 4bdc78d1a987bac8e3313722f7be3097bcd0d232 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 15:24:25 +0000 Subject: [PATCH 004/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 17 ++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 19 +++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 +++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 23 ++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 21 +++++++ .../functions/mongodb-crud/crud_Project.js | 23 ++++++++ .../functions/mongodb-crud/crud_Replace.js | 29 ++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 31 ++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 27 +++++++++ 10 files changed, 267 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..439e551 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,17 @@ +exports = async function(args){ + console.log(JSON.stringify(args)); + + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteMany(args); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..f6355f0 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,19 @@ +exports = async function(deleteFilter){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + // An example deleteFilter: + // { _id: ObjectId("123")} + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..4c52c06 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + const query = { _id: new BSON.ObjectId(saleId) }; + + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}) +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..bc71dd2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,23 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + insertResult = await collection.insertMany(args); + console.log('insertResult ids:', insertResult.insertedIds); + console.log('insertResult length:', insertResult.insertedIds.length); + console.log('returning', JSON.stringify(insertResult)); + return insertResult; + + } catch(err) { + console.log("Failed to insert item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..7a56008 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + // Execute an InsertOne in MongoDB + insertResult = await collection.insertOne(args); + return insertResult; + + } catch(err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..bf73baf --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,23 @@ +exports = async function(saleId, projection={}){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": new BSON.ObjectId(saleId) }; + // An example of the projection object that might be passed in: + /* const projection = { + _id:0, + storeLocation:1, + items: 1 + } */ + try { + doc = await collection.findOne(query, projection); + console.log('found:', JSON.stringify(doc)); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..8d1288f --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,29 @@ +exports = async function(productId, replacement){ + console.log(productId); + console.log(replacement); + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "_id": BSON.ObjectId(productId) }; + // An example replacement ojbect: + /* const replacement = { + "storeLocation": "East Appleton", + "couponUsed": true, + }; */ + +const options = { "returnNewDocument": true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch(err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..49d77eb --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,31 @@ +exports = async function(query, updateFilter){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // Example update filter: + /* const updateFilter = { + "$set": { + "storeId": storeId, + } + }; + */ + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateOne(query, updateFilter, options); + console.log(JSON.stringify(updateResult)); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..9432610 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,27 @@ +exports = async function(productIdToUpdate, updateFilter){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "_id": productIdToUpdate }; + + // example update filter: + /*const updatefilter = { + "$set": { + "price": 20.99, + } + };*/ + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateOne(query, updateFilter, options); + console.log(JSON.stringify(updateResult)); + return updateResult; + + } catch(err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +}; From 6f5153e8157a545009069ce92339c668cc6d6af0 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 15:24:26 +0000 Subject: [PATCH 005/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 12009f8541f096e0ece863f1a8886bfe0d2c0517 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 15:24:28 +0000 Subject: [PATCH 006/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 0c83297b1d8c7359fde622695fbcd57f15d9e548 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 15:24:39 +0000 Subject: [PATCH 007/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index decd721..1292535 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -99df9d23e793387e1d0e6677a1487d7c90265d6d +ae05e55751bbbded2ebf1d105dc3f874e4b08d30 From 29af74411e9f177bf85b8c124b5b254ffca17e38 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 15:24:40 +0000 Subject: [PATCH 008/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 1292535..7f4e292 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -ae05e55751bbbded2ebf1d105dc3f874e4b08d30 +0c83297b1d8c7359fde622695fbcd57f15d9e548 From fc23e223b6e480142fb74b4afaf2d08cbc7dc8ee Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Mon, 17 Jun 2024 08:41:06 -0700 Subject: [PATCH 009/230] test why file changes not getting saved --- .github/workflows/Remove-Function-Name-Prefix.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Remove-Function-Name-Prefix.yml b/.github/workflows/Remove-Function-Name-Prefix.yml index 068ddb0..9f450eb 100644 --- a/.github/workflows/Remove-Function-Name-Prefix.yml +++ b/.github/workflows/Remove-Function-Name-Prefix.yml @@ -27,5 +27,7 @@ jobs: git config --global user.name "ActionBot" git commit -m 'remove function name prefix' git push origin ${{ github.ref }} + else + echo "no changes to commit" fi - echo "done" + echo "done" \ No newline at end of file From 043bc86d7e10b20fc8c69cf9505dc9f1f0333148 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 15:41:25 +0000 Subject: [PATCH 010/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 7f4e292..1abf7c9 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -0c83297b1d8c7359fde622695fbcd57f15d9e548 +fc23e223b6e480142fb74b4afaf2d08cbc7dc8ee From f22c2e6d9ee318d9464d16b9673a01073b495e38 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Mon, 17 Jun 2024 08:42:13 -0700 Subject: [PATCH 011/230] remove conditional --- .github/workflows/Remove-Function-Name-Prefix.yml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/Remove-Function-Name-Prefix.yml b/.github/workflows/Remove-Function-Name-Prefix.yml index 9f450eb..eca37d2 100644 --- a/.github/workflows/Remove-Function-Name-Prefix.yml +++ b/.github/workflows/Remove-Function-Name-Prefix.yml @@ -21,13 +21,9 @@ jobs: mv -n $file $justpath/$justfile fi done - if [ "$(git diff --name-only)" ]; then - git add . - git config --global user.email "caleb.thompson@mongodb.com" - git config --global user.name "ActionBot" - git commit -m 'remove function name prefix' - git push origin ${{ github.ref }} - else - echo "no changes to commit" - fi + git add . + git config --global user.email "caleb.thompson@mongodb.com" + git config --global user.name "ActionBot" + git commit -m 'remove function name prefix' + git push origin ${{ github.ref }} echo "done" \ No newline at end of file From 15d8fe5c6b99e3c35e6652fd08edca9b8d6e884c Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 15:42:38 +0000 Subject: [PATCH 012/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 1abf7c9..20915bc 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -fc23e223b6e480142fb74b4afaf2d08cbc7dc8ee +f22c2e6d9ee318d9464d16b9673a01073b495e38 From dd71b06baa29f8dfe1c0daf27cc9106afe65223a Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Mon, 17 Jun 2024 08:45:31 -0700 Subject: [PATCH 013/230] force move --- .../workflows/Remove-Function-Name-Prefix.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/Remove-Function-Name-Prefix.yml b/.github/workflows/Remove-Function-Name-Prefix.yml index eca37d2..e9fca75 100644 --- a/.github/workflows/Remove-Function-Name-Prefix.yml +++ b/.github/workflows/Remove-Function-Name-Prefix.yml @@ -18,12 +18,16 @@ jobs: justfile="${justfile#*_}" echo "was:" $file echo "saving as" $justpath/$justfile - mv -n $file $justpath/$justfile + mv -f $file $justpath/$justfile fi done - git add . - git config --global user.email "caleb.thompson@mongodb.com" - git config --global user.name "ActionBot" - git commit -m 'remove function name prefix' - git push origin ${{ github.ref }} - echo "done" \ No newline at end of file + if [ "$(git diff --name-only)" ]; then + git add . + git config --global user.email "caleb.thompson@mongodb.com" + git config --global user.name "ActionBot" + git commit -m 'remove function name prefix' + git push origin ${{ github.ref }} + else + echo "no changes to commit" + fi + echo "changes committed" From 84135c824b2d59b435e5b702df6c9b29e2bf20f0 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 15:45:53 +0000 Subject: [PATCH 014/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 20915bc..e2bb201 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -f22c2e6d9ee318d9464d16b9673a01073b495e38 +dd71b06baa29f8dfe1c0daf27cc9106afe65223a From 6092445d00af7eaeba301ed33b6a917bf69052bf Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 15:45:55 +0000 Subject: [PATCH 015/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/DeleteOne.js | 2 +- snippets/functions/mongodb-crud/FindOne.js | 63 +++++++++++++++---- snippets/functions/mongodb-crud/Project.js | 4 +- snippets/functions/mongodb-crud/Replace.js | 6 +- snippets/functions/mongodb-crud/UpdateMany.js | 7 ++- .../functions/mongodb-crud/crud_DeleteMany.js | 17 ----- .../functions/mongodb-crud/crud_DeleteOne.js | 19 ------ snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 56 ----------------- .../functions/mongodb-crud/crud_InsertMany.js | 23 ------- .../functions/mongodb-crud/crud_InsertOne.js | 21 ------- .../functions/mongodb-crud/crud_Project.js | 23 ------- .../functions/mongodb-crud/crud_Replace.js | 29 --------- .../functions/mongodb-crud/crud_UpdateMany.js | 31 --------- .../functions/mongodb-crud/crud_UpdateOne.js | 27 -------- 17 files changed, 61 insertions(+), 311 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/DeleteOne.js b/snippets/functions/mongodb-crud/DeleteOne.js index b29595a..f6355f0 100644 --- a/snippets/functions/mongodb-crud/DeleteOne.js +++ b/snippets/functions/mongodb-crud/DeleteOne.js @@ -3,7 +3,7 @@ exports = async function(deleteFilter){ var dbName = "sample_supplies"; var collName = "sales"; - // example deleteFilter: + // An example deleteFilter: // { _id: ObjectId("123")} var collection = context.services.get(serviceName).db(dbName).collection(collName); diff --git a/snippets/functions/mongodb-crud/FindOne.js b/snippets/functions/mongodb-crud/FindOne.js index 49e99e8..4c52c06 100644 --- a/snippets/functions/mongodb-crud/FindOne.js +++ b/snippets/functions/mongodb-crud/FindOne.js @@ -1,17 +1,56 @@ -exports = async function(saleId){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": new BSON.ObjectId(saleId) }; - try { - doc = await collection.findOne(query); - console.log('found:', JSON.stringify(doc)); - return doc; + const query = { _id: new BSON.ObjectId(saleId) }; + + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; - } catch(err) { - console.log("Failed to find item: ", err.message); + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); return { error: err.message }; } }; + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}) +*/ diff --git a/snippets/functions/mongodb-crud/Project.js b/snippets/functions/mongodb-crud/Project.js index 9bab876..bf73baf 100644 --- a/snippets/functions/mongodb-crud/Project.js +++ b/snippets/functions/mongodb-crud/Project.js @@ -6,11 +6,11 @@ exports = async function(saleId, projection={}){ var collection = context.services.get(serviceName).db(dbName).collection(collName); const query = { "_id": new BSON.ObjectId(saleId) }; // An example of the projection object that might be passed in: - /*const projection = { + /* const projection = { _id:0, storeLocation:1, items: 1 - }*/ + } */ try { doc = await collection.findOne(query, projection); console.log('found:', JSON.stringify(doc)); diff --git a/snippets/functions/mongodb-crud/Replace.js b/snippets/functions/mongodb-crud/Replace.js index 6093bec..8d1288f 100644 --- a/snippets/functions/mongodb-crud/Replace.js +++ b/snippets/functions/mongodb-crud/Replace.js @@ -12,11 +12,11 @@ exports = async function(productId, replacement){ var collection = context.services.get(serviceName).db(dbName).collection(collName); const query = { "_id": BSON.ObjectId(productId) }; - // an example replacement ojbect: - /*const replacement = { + // An example replacement ojbect: + /* const replacement = { "storeLocation": "East Appleton", "couponUsed": true, - };*/ + }; */ const options = { "returnNewDocument": true }; diff --git a/snippets/functions/mongodb-crud/UpdateMany.js b/snippets/functions/mongodb-crud/UpdateMany.js index 41e268f..49d77eb 100644 --- a/snippets/functions/mongodb-crud/UpdateMany.js +++ b/snippets/functions/mongodb-crud/UpdateMany.js @@ -9,12 +9,13 @@ exports = async function(query, updateFilter){ // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - // Exampke update filter: - /*const updateFilter = { + // Example update filter: + /* const updateFilter = { "$set": { "storeId": storeId, } - };*/ + }; + */ const options = { "upsert": false }; diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 439e551..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,17 +0,0 @@ -exports = async function(args){ - console.log(JSON.stringify(args)); - - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteMany(args); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index f6355f0..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,19 +0,0 @@ -exports = async function(deleteFilter){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - // An example deleteFilter: - // { _id: ObjectId("123")} - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 4c52c06..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - const query = { _id: new BSON.ObjectId(saleId) }; - - const replacement = { - storeLocation: "East Appleton", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } -}) -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index bc71dd2..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - insertResult = await collection.insertMany(args); - console.log('insertResult ids:', insertResult.insertedIds); - console.log('insertResult length:', insertResult.insertedIds.length); - console.log('returning', JSON.stringify(insertResult)); - return insertResult; - - } catch(err) { - console.log("Failed to insert item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 7a56008..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - // Execute an InsertOne in MongoDB - insertResult = await collection.insertOne(args); - return insertResult; - - } catch(err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index bf73baf..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(saleId, projection={}){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": new BSON.ObjectId(saleId) }; - // An example of the projection object that might be passed in: - /* const projection = { - _id:0, - storeLocation:1, - items: 1 - } */ - try { - doc = await collection.findOne(query, projection); - console.log('found:', JSON.stringify(doc)); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 8d1288f..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,29 +0,0 @@ -exports = async function(productId, replacement){ - console.log(productId); - console.log(replacement); - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "_id": BSON.ObjectId(productId) }; - // An example replacement ojbect: - /* const replacement = { - "storeLocation": "East Appleton", - "couponUsed": true, - }; */ - -const options = { "returnNewDocument": true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch(err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index 49d77eb..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,31 +0,0 @@ -exports = async function(query, updateFilter){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // Example update filter: - /* const updateFilter = { - "$set": { - "storeId": storeId, - } - }; - */ - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateOne(query, updateFilter, options); - console.log(JSON.stringify(updateResult)); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 9432610..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,27 +0,0 @@ -exports = async function(productIdToUpdate, updateFilter){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "_id": productIdToUpdate }; - - // example update filter: - /*const updatefilter = { - "$set": { - "price": 20.99, - } - };*/ - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateOne(query, updateFilter, options); - console.log(JSON.stringify(updateResult)); - return updateResult; - - } catch(err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -}; From 30155d4ef36a3f85ef2cce4168fb2a29fbc8a610 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 19:53:06 +0000 Subject: [PATCH 016/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 17 ++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 19 +++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 26 +++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 23 ++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 21 +++++++ .../functions/mongodb-crud/crud_Project.js | 23 ++++++++ .../functions/mongodb-crud/crud_Replace.js | 56 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 31 ++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 27 +++++++++ 10 files changed, 264 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..439e551 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,17 @@ +exports = async function(args){ + console.log(JSON.stringify(args)); + + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteMany(args); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..f6355f0 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,19 @@ +exports = async function(deleteFilter){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + // An example deleteFilter: + // { _id: ObjectId("123")} + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..daef971 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,26 @@ +exports = async function(productId){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "productId": productId }; + const projection = { + "title": 1, + "quantity": 1, + } + + try { + doc = await collection.findOne(query, projection); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..bc71dd2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,23 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + insertResult = await collection.insertMany(args); + console.log('insertResult ids:', insertResult.insertedIds); + console.log('insertResult length:', insertResult.insertedIds.length); + console.log('returning', JSON.stringify(insertResult)); + return insertResult; + + } catch(err) { + console.log("Failed to insert item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..7a56008 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + // Execute an InsertOne in MongoDB + insertResult = await collection.insertOne(args); + return insertResult; + + } catch(err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..bf73baf --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,23 @@ +exports = async function(saleId, projection={}){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": new BSON.ObjectId(saleId) }; + // An example of the projection object that might be passed in: + /* const projection = { + _id:0, + storeLocation:1, + items: 1 + } */ + try { + doc = await collection.findOne(query, projection); + console.log('found:', JSON.stringify(doc)); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..aafe530 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,56 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + console.log(changeEvent._id._data); + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..49d77eb --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,31 @@ +exports = async function(query, updateFilter){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // Example update filter: + /* const updateFilter = { + "$set": { + "storeId": storeId, + } + }; + */ + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateOne(query, updateFilter, options); + console.log(JSON.stringify(updateResult)); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..9432610 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,27 @@ +exports = async function(productIdToUpdate, updateFilter){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "_id": productIdToUpdate }; + + // example update filter: + /*const updatefilter = { + "$set": { + "price": 20.99, + } + };*/ + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateOne(query, updateFilter, options); + console.log(JSON.stringify(updateResult)); + return updateResult; + + } catch(err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +}; From 41d3ad4db8a26213f1844d586259ea79fe485a7a Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 19:53:08 +0000 Subject: [PATCH 017/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From d2dee0bc7de76a46c01e1ad3cdd6362446897838 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 19:53:18 +0000 Subject: [PATCH 018/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- snippets/functions/mongodb-crud/FindOne.js | 70 ++++++------------- snippets/functions/mongodb-crud/Replace.js | 67 ++++++++++++------ .../functions/mongodb-crud/crud_DeleteMany.js | 17 ----- .../functions/mongodb-crud/crud_DeleteOne.js | 19 ----- snippets/functions/mongodb-crud/crud_Find.js | 21 ------ .../functions/mongodb-crud/crud_FindOne.js | 26 ------- .../functions/mongodb-crud/crud_InsertMany.js | 23 ------ .../functions/mongodb-crud/crud_InsertOne.js | 21 ------ .../functions/mongodb-crud/crud_Project.js | 23 ------ .../functions/mongodb-crud/crud_Replace.js | 56 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 31 -------- .../functions/mongodb-crud/crud_UpdateOne.js | 27 ------- 13 files changed, 67 insertions(+), 343 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/FindOne.js b/snippets/functions/mongodb-crud/FindOne.js index 4c52c06..daef971 100644 --- a/snippets/functions/mongodb-crud/FindOne.js +++ b/snippets/functions/mongodb-crud/FindOne.js @@ -1,56 +1,26 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); +exports = async function(productId){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; - const query = { _id: new BSON.ObjectId(saleId) }; + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; - const replacement = { - storeLocation: "East Appleton", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "productId": productId }; + const projection = { + "title": 1, + "quantity": 1, } -}; -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + try { + doc = await collection.findOne(query, projection); + return doc; -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; } -}) -*/ +}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/Replace.js b/snippets/functions/mongodb-crud/Replace.js index 8d1288f..aafe530 100644 --- a/snippets/functions/mongodb-crud/Replace.js +++ b/snippets/functions/mongodb-crud/Replace.js @@ -1,29 +1,56 @@ -exports = async function(productId, replacement){ - console.log(productId); - console.log(replacement); - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; + console.log(changeEvent._id._data); + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; - const query = { "_id": BSON.ObjectId(productId) }; - // An example replacement ojbect: - /* const replacement = { - "storeLocation": "East Appleton", - "couponUsed": true, - }; */ - -const options = { "returnNewDocument": true }; + const options = { returnNewDocument: true }; try { return await collection.findOneAndReplace(query, replacement, options); - } catch(err) { + } catch (err) { console.log("Failed to replace item: ", err.message); return { error: err.message }; } -}; \ No newline at end of file +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 439e551..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,17 +0,0 @@ -exports = async function(args){ - console.log(JSON.stringify(args)); - - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteMany(args); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index f6355f0..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,19 +0,0 @@ -exports = async function(deleteFilter){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - // An example deleteFilter: - // { _id: ObjectId("123")} - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index daef971..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,26 +0,0 @@ -exports = async function(productId){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "productId": productId }; - const projection = { - "title": 1, - "quantity": 1, - } - - try { - doc = await collection.findOne(query, projection); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index bc71dd2..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - insertResult = await collection.insertMany(args); - console.log('insertResult ids:', insertResult.insertedIds); - console.log('insertResult length:', insertResult.insertedIds.length); - console.log('returning', JSON.stringify(insertResult)); - return insertResult; - - } catch(err) { - console.log("Failed to insert item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 7a56008..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - // Execute an InsertOne in MongoDB - insertResult = await collection.insertOne(args); - return insertResult; - - } catch(err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index bf73baf..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(saleId, projection={}){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": new BSON.ObjectId(saleId) }; - // An example of the projection object that might be passed in: - /* const projection = { - _id:0, - storeLocation:1, - items: 1 - } */ - try { - doc = await collection.findOne(query, projection); - console.log('found:', JSON.stringify(doc)); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index aafe530..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - console.log(changeEvent._id._data); - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const replacement = { - storeLocation: "East Appleton", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -} - -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } -}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index 49d77eb..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,31 +0,0 @@ -exports = async function(query, updateFilter){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // Example update filter: - /* const updateFilter = { - "$set": { - "storeId": storeId, - } - }; - */ - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateOne(query, updateFilter, options); - console.log(JSON.stringify(updateResult)); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 9432610..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,27 +0,0 @@ -exports = async function(productIdToUpdate, updateFilter){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "_id": productIdToUpdate }; - - // example update filter: - /*const updatefilter = { - "$set": { - "price": 20.99, - } - };*/ - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateOne(query, updateFilter, options); - console.log(JSON.stringify(updateResult)); - return updateResult; - - } catch(err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -}; From 1e214a01a25f52b131a696427a100b2fec29f64b Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 19:53:19 +0000 Subject: [PATCH 019/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index e2bb201..0a4a6cb 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -dd71b06baa29f8dfe1c0daf27cc9106afe65223a +d2dee0bc7de76a46c01e1ad3cdd6362446897838 From 332ecb3553bc4fe7a09d1a40e26a8f1de69fda9f Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 19:53:31 +0000 Subject: [PATCH 020/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 0a4a6cb..88036e3 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -d2dee0bc7de76a46c01e1ad3cdd6362446897838 +1e214a01a25f52b131a696427a100b2fec29f64b From 148e1f8ec38f77988b240f8959ea8f2a85823f24 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 23:07:04 +0000 Subject: [PATCH 021/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 17 ++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 19 +++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 26 +++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 23 ++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 21 +++++++ .../functions/mongodb-crud/crud_Project.js | 23 ++++++++ .../functions/mongodb-crud/crud_Replace.js | 55 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 31 +++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 53 ++++++++++++++++++ 10 files changed, 289 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..439e551 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,17 @@ +exports = async function(args){ + console.log(JSON.stringify(args)); + + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteMany(args); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..f6355f0 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,19 @@ +exports = async function(deleteFilter){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + // An example deleteFilter: + // { _id: ObjectId("123")} + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..b19d70e --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,26 @@ +exports = async function(_id){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "_id": new BSON.ObjectId(_id) }; + const projection = { + "title": 1, + "quantity": 1, + } + + try { + doc = await collection.findOne(query, projection); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..bc71dd2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,23 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + insertResult = await collection.insertMany(args); + console.log('insertResult ids:', insertResult.insertedIds); + console.log('insertResult length:', insertResult.insertedIds.length); + console.log('returning', JSON.stringify(insertResult)); + return insertResult; + + } catch(err) { + console.log("Failed to insert item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..7a56008 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + // Execute an InsertOne in MongoDB + insertResult = await collection.insertOne(args); + return insertResult; + + } catch(err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..bf73baf --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,23 @@ +exports = async function(saleId, projection={}){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": new BSON.ObjectId(saleId) }; + // An example of the projection object that might be passed in: + /* const projection = { + _id:0, + storeLocation:1, + items: 1 + } */ + try { + doc = await collection.findOne(query, projection); + console.log('found:', JSON.stringify(doc)); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..d99b634 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,55 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..49d77eb --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,31 @@ +exports = async function(query, updateFilter){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // Example update filter: + /* const updateFilter = { + "$set": { + "storeId": storeId, + } + }; + */ + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateOne(query, updateFilter, options); + console.log(JSON.stringify(updateResult)); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..8353adf --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,53 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file From ca429bcc23a51ae0193558260cbada79890be8bd Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 23:07:05 +0000 Subject: [PATCH 022/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 7f1c9637d1e55908f48b933d8d3e67bd26b49918 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 23:07:07 +0000 Subject: [PATCH 023/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 7a7f8beb0e09d51323d9f90f11d71ab8bb4e60a1 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 23:07:15 +0000 Subject: [PATCH 024/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ---- snippets/functions/mongodb-crud/FindOne.js | 4 +- snippets/functions/mongodb-crud/Replace.js | 1 - snippets/functions/mongodb-crud/UpdateOne.js | 70 +++++++++++++------ .../functions/mongodb-crud/crud_DeleteMany.js | 17 ----- .../functions/mongodb-crud/crud_DeleteOne.js | 19 ----- snippets/functions/mongodb-crud/crud_Find.js | 21 ------ .../functions/mongodb-crud/crud_FindOne.js | 26 ------- .../functions/mongodb-crud/crud_InsertMany.js | 23 ------ .../functions/mongodb-crud/crud_InsertOne.js | 21 ------ .../functions/mongodb-crud/crud_Project.js | 23 ------ .../functions/mongodb-crud/crud_Replace.js | 55 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 31 -------- .../functions/mongodb-crud/crud_UpdateOne.js | 53 -------------- 15 files changed, 50 insertions(+), 337 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/FindOne.js b/snippets/functions/mongodb-crud/FindOne.js index daef971..b19d70e 100644 --- a/snippets/functions/mongodb-crud/FindOne.js +++ b/snippets/functions/mongodb-crud/FindOne.js @@ -1,4 +1,4 @@ -exports = async function(productId){ +exports = async function(_id){ // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) var serviceName = "mongodb-atlas"; @@ -9,7 +9,7 @@ exports = async function(productId){ // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "productId": productId }; + const query = { "_id": new BSON.ObjectId(_id) }; const projection = { "title": 1, "quantity": 1, diff --git a/snippets/functions/mongodb-crud/Replace.js b/snippets/functions/mongodb-crud/Replace.js index aafe530..d99b634 100644 --- a/snippets/functions/mongodb-crud/Replace.js +++ b/snippets/functions/mongodb-crud/Replace.js @@ -4,7 +4,6 @@ exports = async function (changeEvent) { .db("sample_supplies") .collection("sales"); - console.log(changeEvent._id._data); const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; const replacement = { diff --git a/snippets/functions/mongodb-crud/UpdateOne.js b/snippets/functions/mongodb-crud/UpdateOne.js index 9432610..8353adf 100644 --- a/snippets/functions/mongodb-crud/UpdateOne.js +++ b/snippets/functions/mongodb-crud/UpdateOne.js @@ -1,27 +1,53 @@ -exports = async function(productIdToUpdate, updateFilter){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - var collection = context.services.get(serviceName).db(dbName).collection(collName); +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); - const query = { "_id": productIdToUpdate }; - - // example update filter: - /*const updatefilter = { - "$set": { - "price": 20.99, - } - };*/ - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateOne(query, updateFilter, options); - console.log(JSON.stringify(updateResult)); - return updateResult; + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; - } catch(err) { + try { + return await collection.updateOne(query, updateFields); + } catch (err) { console.log("Failed to update item: ", err.message); return { error: err.message }; } -}; +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 439e551..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,17 +0,0 @@ -exports = async function(args){ - console.log(JSON.stringify(args)); - - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteMany(args); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index f6355f0..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,19 +0,0 @@ -exports = async function(deleteFilter){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - // An example deleteFilter: - // { _id: ObjectId("123")} - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index b19d70e..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,26 +0,0 @@ -exports = async function(_id){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "_id": new BSON.ObjectId(_id) }; - const projection = { - "title": 1, - "quantity": 1, - } - - try { - doc = await collection.findOne(query, projection); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index bc71dd2..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - insertResult = await collection.insertMany(args); - console.log('insertResult ids:', insertResult.insertedIds); - console.log('insertResult length:', insertResult.insertedIds.length); - console.log('returning', JSON.stringify(insertResult)); - return insertResult; - - } catch(err) { - console.log("Failed to insert item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 7a56008..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - // Execute an InsertOne in MongoDB - insertResult = await collection.insertOne(args); - return insertResult; - - } catch(err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index bf73baf..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(saleId, projection={}){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": new BSON.ObjectId(saleId) }; - // An example of the projection object that might be passed in: - /* const projection = { - _id:0, - storeLocation:1, - items: 1 - } */ - try { - doc = await collection.findOne(query, projection); - console.log('found:', JSON.stringify(doc)); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index d99b634..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,55 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const replacement = { - storeLocation: "East Appleton", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -} - -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } -}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index 49d77eb..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,31 +0,0 @@ -exports = async function(query, updateFilter){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // Example update filter: - /* const updateFilter = { - "$set": { - "storeId": storeId, - } - }; - */ - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateOne(query, updateFilter, options); - console.log(JSON.stringify(updateResult)); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 8353adf..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,53 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } -}*/ \ No newline at end of file From 387766711c1546210678901b097902e0aed6b2b5 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 23:07:16 +0000 Subject: [PATCH 025/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 88036e3..9e8f44e 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -1e214a01a25f52b131a696427a100b2fec29f64b +7a7f8beb0e09d51323d9f90f11d71ab8bb4e60a1 From 0c3fc49d39f6d9247adb8eb0f83a230aaadc5c8e Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 23:07:17 +0000 Subject: [PATCH 026/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 9e8f44e..948cf84 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -7a7f8beb0e09d51323d9f90f11d71ab8bb4e60a1 +387766711c1546210678901b097902e0aed6b2b5 From 892e506a9693cb74ad96368213aa89df1238fcca Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 23:13:02 +0000 Subject: [PATCH 027/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 17 ++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 19 +++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 22 ++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 23 ++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 21 +++++++ .../functions/mongodb-crud/crud_Project.js | 23 ++++++++ .../functions/mongodb-crud/crud_Replace.js | 55 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 31 +++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 53 ++++++++++++++++++ 10 files changed, 285 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..439e551 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,17 @@ +exports = async function(args){ + console.log(JSON.stringify(args)); + + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteMany(args); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..f6355f0 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,19 @@ +exports = async function(deleteFilter){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + // An example deleteFilter: + // { _id: ObjectId("123")} + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..c65672e --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,22 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..bc71dd2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,23 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + insertResult = await collection.insertMany(args); + console.log('insertResult ids:', insertResult.insertedIds); + console.log('insertResult length:', insertResult.insertedIds.length); + console.log('returning', JSON.stringify(insertResult)); + return insertResult; + + } catch(err) { + console.log("Failed to insert item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..7a56008 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + // Execute an InsertOne in MongoDB + insertResult = await collection.insertOne(args); + return insertResult; + + } catch(err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..bf73baf --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,23 @@ +exports = async function(saleId, projection={}){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": new BSON.ObjectId(saleId) }; + // An example of the projection object that might be passed in: + /* const projection = { + _id:0, + storeLocation:1, + items: 1 + } */ + try { + doc = await collection.findOne(query, projection); + console.log('found:', JSON.stringify(doc)); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..d99b634 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,55 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..49d77eb --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,31 @@ +exports = async function(query, updateFilter){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // Example update filter: + /* const updateFilter = { + "$set": { + "storeId": storeId, + } + }; + */ + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateOne(query, updateFilter, options); + console.log(JSON.stringify(updateResult)); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..8353adf --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,53 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file From 39d1e05778b9d16fe9dfc71d93ddd8d770e53573 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 23:13:04 +0000 Subject: [PATCH 028/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 608fadc47448901b594a1944dde799f8a75cde3d Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 17 Jun 2024 23:13:05 +0000 Subject: [PATCH 029/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 8c6165825666f5a4a71da281c59d17521ab3f9cf Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 23:13:13 +0000 Subject: [PATCH 030/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 948cf84..67669f2 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -387766711c1546210678901b097902e0aed6b2b5 +8e6c0559fa3c25ea57a8a80ed2e434542eb5649e From 75032de96b8764a9f6694fed55211ba46bd65521 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 23:13:14 +0000 Subject: [PATCH 031/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/FindOne.js | 10 +--- .../functions/mongodb-crud/crud_DeleteMany.js | 17 ------ .../functions/mongodb-crud/crud_DeleteOne.js | 19 ------- snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 22 -------- .../functions/mongodb-crud/crud_InsertMany.js | 23 -------- .../functions/mongodb-crud/crud_InsertOne.js | 21 ------- .../functions/mongodb-crud/crud_Project.js | 23 -------- .../functions/mongodb-crud/crud_Replace.js | 55 ------------------- .../functions/mongodb-crud/crud_UpdateMany.js | 31 ----------- .../functions/mongodb-crud/crud_UpdateOne.js | 53 ------------------ 13 files changed, 3 insertions(+), 315 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/FindOne.js b/snippets/functions/mongodb-crud/FindOne.js index b19d70e..c65672e 100644 --- a/snippets/functions/mongodb-crud/FindOne.js +++ b/snippets/functions/mongodb-crud/FindOne.js @@ -1,4 +1,4 @@ -exports = async function(_id){ +exports = async function(changeEvent){ // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) var serviceName = "mongodb-atlas"; @@ -9,14 +9,10 @@ exports = async function(_id){ // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": new BSON.ObjectId(_id) }; - const projection = { - "title": 1, - "quantity": 1, - } + const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; try { - doc = await collection.findOne(query, projection); + doc = await collection.findOne(query); return doc; } catch(err) { diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 439e551..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,17 +0,0 @@ -exports = async function(args){ - console.log(JSON.stringify(args)); - - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteMany(args); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index f6355f0..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,19 +0,0 @@ -exports = async function(deleteFilter){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - // An example deleteFilter: - // { _id: ObjectId("123")} - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index c65672e..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,22 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index bc71dd2..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - insertResult = await collection.insertMany(args); - console.log('insertResult ids:', insertResult.insertedIds); - console.log('insertResult length:', insertResult.insertedIds.length); - console.log('returning', JSON.stringify(insertResult)); - return insertResult; - - } catch(err) { - console.log("Failed to insert item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 7a56008..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - // Execute an InsertOne in MongoDB - insertResult = await collection.insertOne(args); - return insertResult; - - } catch(err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index bf73baf..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(saleId, projection={}){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": new BSON.ObjectId(saleId) }; - // An example of the projection object that might be passed in: - /* const projection = { - _id:0, - storeLocation:1, - items: 1 - } */ - try { - doc = await collection.findOne(query, projection); - console.log('found:', JSON.stringify(doc)); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index d99b634..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,55 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const replacement = { - storeLocation: "East Appleton", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -} - -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } -}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index 49d77eb..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,31 +0,0 @@ -exports = async function(query, updateFilter){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // Example update filter: - /* const updateFilter = { - "$set": { - "storeId": storeId, - } - }; - */ - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateOne(query, updateFilter, options); - console.log(JSON.stringify(updateResult)); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 8353adf..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,53 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } -}*/ \ No newline at end of file From 2a3130fbc38cb4f22d120d7caf9ef04f73e3adff Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 17 Jun 2024 23:13:16 +0000 Subject: [PATCH 032/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 67669f2..a00074f 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -8e6c0559fa3c25ea57a8a80ed2e434542eb5649e +75032de96b8764a9f6694fed55211ba46bd65521 From 488f71adc7708f8853bce663b6396e3895c6b1a1 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Mon, 17 Jun 2024 12:53:32 -0700 Subject: [PATCH 033/230] wip --- .../__tests__/functions-mongodb-crud.tests.ts | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/tests/integration/__tests__/functions-mongodb-crud.tests.ts b/tests/integration/__tests__/functions-mongodb-crud.tests.ts index 8bda687..cbcd370 100644 --- a/tests/integration/__tests__/functions-mongodb-crud.tests.ts +++ b/tests/integration/__tests__/functions-mongodb-crud.tests.ts @@ -205,6 +205,35 @@ describe("Test MongoDB CRUD operations in Functions", () => { "storeLocation": "East Appleton", "couponUsed": true }*/ + + + let changeEvent = { + _id: {_data: ids[0] }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } + }; const updateOneFilter = { "storeLocation": "Camden", @@ -212,9 +241,10 @@ describe("Test MongoDB CRUD operations in Functions", () => { }; let count:number = 0; + let updateOneResult; try { - const updateOneResult = (await user.functions.crud_UpdateOne( - ids[1], updateOneFilter)) as UpdateResult; + updateOneResult = (await user.functions.crud_UpdateOne( + changeEvent)) as UpdateResult; count = updateOneResult.modifiedCount; } catch (error) { if (error instanceof Error) { @@ -223,6 +253,7 @@ describe("Test MongoDB CRUD operations in Functions", () => { } expect(count).toBe(1); + console.log(updateOneResult) //you have to find the updated doc; it is not returned // *********** // From e54b547856363442cc2555b783954e7a791529c1 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 18 Jun 2024 10:10:11 -0700 Subject: [PATCH 034/230] update unit tests to use changeEvent --- .../__tests__/functions-mongodb-crud.tests.ts | 157 +++++++++--------- 1 file changed, 81 insertions(+), 76 deletions(-) diff --git a/tests/integration/__tests__/functions-mongodb-crud.tests.ts b/tests/integration/__tests__/functions-mongodb-crud.tests.ts index cbcd370..886b6c2 100644 --- a/tests/integration/__tests__/functions-mongodb-crud.tests.ts +++ b/tests/integration/__tests__/functions-mongodb-crud.tests.ts @@ -80,6 +80,7 @@ describe("Test MongoDB CRUD operations in Functions", () => { insertOneArgs )) as InsertOneResult; + if (insertResult.insertedId instanceof ObjectId) { resultId = insertResult.insertedId; } @@ -143,7 +144,7 @@ describe("Test MongoDB CRUD operations in Functions", () => { // *********** // // Project // - let projectResult: Sale = new Sale(); + let projectResult; const projectionFilter = { _id:0, @@ -152,8 +153,9 @@ describe("Test MongoDB CRUD operations in Functions", () => { }; try { - projectResult = (await user.functions.crud_FindOne( + projectResult = (await user.functions.crud_Project( ids[0].toString(), projectionFilter)) as Sale; + } catch (error) { if (error instanceof Error) { fail(error.message); @@ -161,10 +163,38 @@ describe("Test MongoDB CRUD operations in Functions", () => { } expect(projectResult).not.toBeNull; - expect(projectResult.storeLocation).not.toBeNull; + /* expect(projectResult.storeLocation).not.toBeNull; expect(projectResult.storeLocation).toBe("Scranton"); expect(projectResult.items?.length).toBe(2); - expect(projectResult.saleDate).toBeNull; + expect(projectResult.saleDate).toBeNull;*/ + + const changeEvent = { + _id: {_data: ids[0].toString() }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } + }; // *********** // @@ -176,25 +206,21 @@ describe("Test MongoDB CRUD operations in Functions", () => { "storeLocation": "East Appleton", "couponUsed": true }*/ - let replaceResult: Sale = new Sale(); - const updateFilter = { - "storeLocation": "East Appleton", - "couponUsed": true, - }; + let replaceResult: Sale = new Sale(); try { - replaceResult = (await user.functions.crud_Replace( - ids[1].toString(), updateFilter)) as Sale; + replaceResult = await user.functions.crud_Replace( + changeEvent) as Sale; } catch (error) { if (error instanceof Error) { fail(error.message); } } - - expect(replaceResult).not.toBeNull; - expect(replaceResult.couponUsed).toBeTruthy(); + + expect(replaceResult.couponUsed).toBe(false); expect(replaceResult.storeLocation).toBe("East Appleton"); + // *********** // // UPDATEONE // @@ -205,70 +231,33 @@ describe("Test MongoDB CRUD operations in Functions", () => { "storeLocation": "East Appleton", "couponUsed": true }*/ - - - let changeEvent = { - _id: {_data: ids[0] }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' + + let updateResult: Sale = new Sale(); + + try { + updateResult = await user.functions.crud_UpdateOne( + changeEvent) as Sale; + } catch (error) { + if (error instanceof Error) { + fail(error.message); } - }; - - const updateOneFilter = { - "storeLocation": "Camden", - "customer": 123, - }; - - let count:number = 0; - let updateOneResult; - try { - updateOneResult = (await user.functions.crud_UpdateOne( - changeEvent)) as UpdateResult; - count = updateOneResult.modifiedCount; - } catch (error) { - if (error instanceof Error) { - fail(error.message); } - } - - expect(count).toBe(1); - console.log(updateOneResult) - //you have to find the updated doc; it is not returned + // *********** // // FindOne // -let findResult: Sale = new Sale(); - try { - findResult = (await user.functions.crud_FindOne( - ids[1].toString(), {})) as Sale; - } catch (error) { - if (error instanceof Error) { - fail(error.message); + + let updatedDocumentResult: Sale = new Sale(); + try { + updatedDocumentResult = await user.functions.crud_FindOne( + changeEvent) as Sale; + } catch (error) { + if (error instanceof Error) { + fail(error.message); + } } - } - expect(findResult.customer).toBe(123); - expect(findResult.storeLocation).toBe("Camden"); + expect(updatedDocumentResult.couponUsed).toBe(true) + expect(updatedDocumentResult.storeLocation).toBe("West Appleton"); // *********** // @@ -280,7 +269,8 @@ let findResult: Sale = new Sale(); "storeLocation": "East Appleton", "couponUsed": true }*/ - + let count; + const updateManyFindFilter = { "purchaseMethod": "Carrier Pigeon" }; @@ -322,9 +312,9 @@ let findResult: Sale = new Sale(); // *********** // // DeleteOne // - const deleteResult = (await user.functions.crud_DeleteOne( + const deleteResult = await user.functions.crud_DeleteOne( {purchaseMethod: "Trinkets"} - )) as DeleteResult; + ) as DeleteResult; expect(deleteResult).toBe(1); // *********** // @@ -338,7 +328,7 @@ let findResult: Sale = new Sale(); //TODO: investigate tear-down style test so this always works //expect(deleteManyCount).toBe(2); -}, 3000); +}, 6000); }) /* @@ -355,4 +345,19 @@ order of tests: ✓ DeleteOne ✓ DeleteMany +*/ + +/* +UPDATED WITH CHANGE EVENT + + InsertOne + InsertMany +✓ FindOne + Project +✓ Replace +✓ UpdateOne + UpdateMany + Find + DeleteOne + DeleteMany */ \ No newline at end of file From ade04a8079c1c0116dc9d54ec701b30c02632cc3 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 18 Jun 2024 17:10:40 +0000 Subject: [PATCH 035/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index a00074f..c93dae6 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -75032de96b8764a9f6694fed55211ba46bd65521 +e54b547856363442cc2555b783954e7a791529c1 From f380c253605da9ef0c4c4358e370b070295de435 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 18 Jun 2024 10:15:35 -0700 Subject: [PATCH 036/230] force deleteOne to delete the first message --- tests/integration/__tests__/functions-mongodb-crud.tests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/__tests__/functions-mongodb-crud.tests.ts b/tests/integration/__tests__/functions-mongodb-crud.tests.ts index 886b6c2..c9154d9 100644 --- a/tests/integration/__tests__/functions-mongodb-crud.tests.ts +++ b/tests/integration/__tests__/functions-mongodb-crud.tests.ts @@ -313,7 +313,7 @@ describe("Test MongoDB CRUD operations in Functions", () => { // *********** // // DeleteOne // const deleteResult = await user.functions.crud_DeleteOne( - {purchaseMethod: "Trinkets"} + {} ) as DeleteResult; expect(deleteResult).toBe(1); From 18923cec653a3a7425b512085144a269fed56f9f Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 18 Jun 2024 17:16:23 +0000 Subject: [PATCH 037/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index c93dae6..a81ce68 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -e54b547856363442cc2555b783954e7a791529c1 +f380c253605da9ef0c4c4358e370b070295de435 From 5865dcf69a4ed309a54b960964123186596f155f Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Thu, 20 Jun 2024 12:11:18 -0700 Subject: [PATCH 038/230] renove old files --- snippets/triggers/match/match_update.json | 5 ----- snippets/triggers/project/project_update.json | 8 -------- 2 files changed, 13 deletions(-) delete mode 100644 snippets/triggers/match/match_update.json delete mode 100644 snippets/triggers/project/project_update.json diff --git a/snippets/triggers/match/match_update.json b/snippets/triggers/match/match_update.json deleted file mode 100644 index ca92fda..0000000 --- a/snippets/triggers/match/match_update.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "updateDescription.updatedFields": { - "status": "blocked" - } -} diff --git a/snippets/triggers/project/project_update.json b/snippets/triggers/project/project_update.json deleted file mode 100644 index 47500bb..0000000 --- a/snippets/triggers/project/project_update.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "operationType": { - "$numberInt": "1" - }, - "updateDescription.updatedFields.FieldA": { - "$numberInt": "1" - } -} From 8735be18fc511c8eeb66b51f4ac739cd05802bb1 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Thu, 20 Jun 2024 19:11:33 +0000 Subject: [PATCH 039/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index a81ce68..ce5012d 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -f380c253605da9ef0c4c4358e370b070295de435 +5865dcf69a4ed309a54b960964123186596f155f From 0d59244f48afbd48b92fbb4d7a0faa60abe84592 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Thu, 20 Jun 2024 19:48:34 +0000 Subject: [PATCH 040/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 17 ++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 19 +++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 22 ++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 23 ++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 21 +++++++ .../functions/mongodb-crud/crud_Project.js | 23 ++++++++ .../functions/mongodb-crud/crud_Replace.js | 55 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 31 +++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 53 ++++++++++++++++++ 10 files changed, 285 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..439e551 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,17 @@ +exports = async function(args){ + console.log(JSON.stringify(args)); + + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteMany(args); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..f6355f0 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,19 @@ +exports = async function(deleteFilter){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + // An example deleteFilter: + // { _id: ObjectId("123")} + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..c65672e --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,22 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..bc71dd2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,23 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + insertResult = await collection.insertMany(args); + console.log('insertResult ids:', insertResult.insertedIds); + console.log('insertResult length:', insertResult.insertedIds.length); + console.log('returning', JSON.stringify(insertResult)); + return insertResult; + + } catch(err) { + console.log("Failed to insert item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..7a56008 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + // Execute an InsertOne in MongoDB + insertResult = await collection.insertOne(args); + return insertResult; + + } catch(err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..bf73baf --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,23 @@ +exports = async function(saleId, projection={}){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": new BSON.ObjectId(saleId) }; + // An example of the projection object that might be passed in: + /* const projection = { + _id:0, + storeLocation:1, + items: 1 + } */ + try { + doc = await collection.findOne(query, projection); + console.log('found:', JSON.stringify(doc)); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..d99b634 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,55 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..49d77eb --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,31 @@ +exports = async function(query, updateFilter){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // Example update filter: + /* const updateFilter = { + "$set": { + "storeId": storeId, + } + }; + */ + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateOne(query, updateFilter, options); + console.log(JSON.stringify(updateResult)); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..8353adf --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,53 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file From 459fd929954287741ee44754810e66dceb9a36f2 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Thu, 20 Jun 2024 19:48:35 +0000 Subject: [PATCH 041/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 5507db91170eb2344e89eb6ea0ee43d4569811d7 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Thu, 20 Jun 2024 19:48:36 +0000 Subject: [PATCH 042/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 8fa9d61a3d6dbe413c1ce6665c0cba6fc2d61f67 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Thu, 20 Jun 2024 19:48:45 +0000 Subject: [PATCH 043/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- .../functions/mongodb-crud/crud_DeleteMany.js | 17 ------ .../functions/mongodb-crud/crud_DeleteOne.js | 19 ------- snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 22 -------- .../functions/mongodb-crud/crud_InsertMany.js | 23 -------- .../functions/mongodb-crud/crud_InsertOne.js | 21 ------- .../functions/mongodb-crud/crud_Project.js | 23 -------- .../functions/mongodb-crud/crud_Replace.js | 55 ------------------- .../functions/mongodb-crud/crud_UpdateMany.js | 31 ----------- .../functions/mongodb-crud/crud_UpdateOne.js | 53 ------------------ 12 files changed, 308 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 439e551..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,17 +0,0 @@ -exports = async function(args){ - console.log(JSON.stringify(args)); - - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteMany(args); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index f6355f0..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,19 +0,0 @@ -exports = async function(deleteFilter){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - // An example deleteFilter: - // { _id: ObjectId("123")} - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index c65672e..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,22 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index bc71dd2..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - insertResult = await collection.insertMany(args); - console.log('insertResult ids:', insertResult.insertedIds); - console.log('insertResult length:', insertResult.insertedIds.length); - console.log('returning', JSON.stringify(insertResult)); - return insertResult; - - } catch(err) { - console.log("Failed to insert item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 7a56008..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - // Execute an InsertOne in MongoDB - insertResult = await collection.insertOne(args); - return insertResult; - - } catch(err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index bf73baf..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,23 +0,0 @@ -exports = async function(saleId, projection={}){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": new BSON.ObjectId(saleId) }; - // An example of the projection object that might be passed in: - /* const projection = { - _id:0, - storeLocation:1, - items: 1 - } */ - try { - doc = await collection.findOne(query, projection); - console.log('found:', JSON.stringify(doc)); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index d99b634..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,55 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const replacement = { - storeLocation: "East Appleton", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -} - -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } -}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index 49d77eb..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,31 +0,0 @@ -exports = async function(query, updateFilter){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // Example update filter: - /* const updateFilter = { - "$set": { - "storeId": storeId, - } - }; - */ - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateOne(query, updateFilter, options); - console.log(JSON.stringify(updateResult)); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -}; diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 8353adf..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,53 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } -}*/ \ No newline at end of file From 73cd5f837244a0829c4e91f2fbfa3889198b5b6e Mon Sep 17 00:00:00 2001 From: ActionBot Date: Thu, 20 Jun 2024 19:48:48 +0000 Subject: [PATCH 044/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index ce5012d..9f1eb2f 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -5865dcf69a4ed309a54b960964123186596f155f +8fa9d61a3d6dbe413c1ce6665c0cba6fc2d61f67 From 3da08d982bc2e20360b3402e455a047392539a6c Mon Sep 17 00:00:00 2001 From: ActionBot Date: Thu, 20 Jun 2024 19:48:51 +0000 Subject: [PATCH 045/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 9f1eb2f..045d924 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -8fa9d61a3d6dbe413c1ce6665c0cba6fc2d61f67 +73cd5f837244a0829c4e91f2fbfa3889198b5b6e From e9961e9d05d8b955e41e9eafe140a2de4dfd5a41 Mon Sep 17 00:00:00 2001 From: MongoCaleb <32645888+MongoCaleb@users.noreply.github.com> Date: Thu, 20 Jun 2024 15:07:22 -0700 Subject: [PATCH 046/230] Development (#45) * update diagram and readme --- Flow Diagram.graffle | Bin 197508 -> 215942 bytes Flow Diagram.png | Bin 146136 -> 0 bytes GitHubActionProcesses.png | Bin 0 -> 157725 bytes README.md | 65 ++++++++++++++++++++++++-------------- latestCommit.md | 2 +- 5 files changed, 42 insertions(+), 25 deletions(-) delete mode 100644 Flow Diagram.png create mode 100644 GitHubActionProcesses.png diff --git a/Flow Diagram.graffle b/Flow Diagram.graffle index 43157eff7651aa6a874c6e9424131d1397692449..3dea20b8906d2fe8188f4ad3bc0f1b825715b344 100644 GIT binary patch literal 215942 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 z z5Koq$m$bWtp~lnr&ChMv7Y+B}8=l`+gYh}ofrtAFBUA1H%GT#|7$v`#zL9!w6(ihx zs8fcwrrHqNzxkmhG$2jr-Xq~(O&?lr{1Cc!?()<{pXUdo7{qtqvJ<)Kx0&T;K*oV9 zc+{HItPX?}N7z}#5%QX=?8Sx@)pCeT#lfijcul#Ao~r$X$F35-a&zU6CzLk{7fvFp zKMksN8RyF>l;EP~7oayx#S6bCe&&8vjXTempFidLPP(l2?bEeuhC)eiw$Iq>7?{4C z()4~8knqyVV&M7RxiElWDIrk_*uEi;oGtK?w5gIyl8;_GbYh;F;6 z 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͒k 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 Pfj?8jeFjB(n6Uo^i>^HO diff --git a/GitHubActionProcesses.png b/GitHubActionProcesses.png new file mode 100644 index 0000000000000000000000000000000000000000..7971fc8bb2b491a19e34b8153e82aa21f0be31de GIT binary patch literal 157725 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 z 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 +When you add a new function, be sure to: + +1. Add a Function or Trigger to the Atlas backend (ask Dev Docs for details + and access). Follow these rules when creating a function or trigger: + + - Function names **must** start with their type, which is one of `api_`, + `crud_`, or `context_`. + - Functions must be tested within the AAS app. + - Triggers should use the "fake_function_for_expressions" + function, since we're only creating triggers to extract the ``match`` and ``project`` stages and nothing function-related. Following this rule means we don't end up with any additional functions in the repo. + +2. Deploy your changes. This will automatically push the changes to the *source* repo, where github actions will remove function name prefixes, extract the ``match`` and ``project`` json from the triggers, and then copy the functions and expressions to this repo. + +3. Update the `manifest.json` file in the correct subfolder (snippets/functions/crud, for example) with your new function. Be sure to generate a new uuid for the `id` field. + +4. Add a relevant test for the function or trigger to the test suite. Refer to the README in the `test/integration` directory for more details. + +## Adding a New Function Category + +If we decide we need a type of function beyond CRUD, function context, third-party integration, and API calls, do the following: + +1. Coordinate with dev and product for naming the new `viewType` and subfolder. +2. Create the new subfolder that will contain these functions. +3. Copy an existing `manifest.json` file from one of the other function types and update it with the following: + a. The new `viewType` + b. The new snippets. Even if there is only 1 new snippet, be sure it is in an array. +4. In the `atlas-functions-triggers-source` repo, you **must** update the `/.github/workflows/Copy-Functions-to-Examples-Repo.yml` action to copy the new category functions. Each function category has a section in the github action that looks like this: +``` + - name: Copy API Functions + uses: MongoCaleb/copy-push-files@main + env: + API_TOKEN_GITHUB: "${{ secrets.API_TOKEN_GITHUB }}" + with: + source_files: ./functions/api_* + remote_repository: https://github.com/mongodb/atlas-functions-triggers-examples + target_dir: "snippets/functions/api-functions/" + target_branch: "development" + access_token: "${{ secrets.API_TOKEN_GITHUB }}" + ``` +Copy one of these sections and change the `source_files`, `target_dir` values. \ No newline at end of file diff --git a/latestCommit.md b/latestCommit.md index 045d924..dd98df2 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -73cd5f837244a0829c4e91f2fbfa3889198b5b6e +3da120c7b4ae701f83af6515e54ac542844eace8 From b4c81171823e7a64f9402209fd2eabb7d42b6d52 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Thu, 20 Jun 2024 22:07:34 +0000 Subject: [PATCH 047/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index dd98df2..5aefd6f 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -3da120c7b4ae701f83af6515e54ac542844eace8 +e9961e9d05d8b955e41e9eafe140a2de4dfd5a41 From 5543c19f39c560bace5639f4848e5ce0934f77ef Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 16:59:22 +0000 Subject: [PATCH 048/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 22 +++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 ++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 55 +++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 60 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 +++++++++++++++++ 10 files changed, 455 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..c65672e --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,22 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..5c66a83 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..d99b634 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,55 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +} + +// To test the above example, insert the following document into your collection: +// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} + +// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + userName: 'alice123', + name: 'Alice' + } +}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..a95c038 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,60 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "West Appleton" + } + }; + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 71db07562229e8a73e2d6f38682278bee4ba64a5 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 16:59:25 +0000 Subject: [PATCH 049/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From b3cea534fd1b067ff8357b1cc3db7d0e8a772d5e Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 16:59:26 +0000 Subject: [PATCH 050/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From c2b919b895bca9972c062ff679d9795e9f382ae6 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 16:59:35 +0000 Subject: [PATCH 051/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 5aefd6f..8231d64 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -e9961e9d05d8b955e41e9eafe140a2de4dfd5a41 +7fa3d3821bcb613c278df4aa6a4c2690e3d5b0cd From f7dd10b47071049b5d7abdafa822d3452adf1257 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 16:59:37 +0000 Subject: [PATCH 052/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 8231d64..334ebb0 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -7fa3d3821bcb613c278df4aa6a4c2690e3d5b0cd +c2b919b895bca9972c062ff679d9795e9f382ae6 From 4c8406641c78b60c868316effe5629bf1137864c Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 16:59:39 +0000 Subject: [PATCH 053/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 334ebb0..9fababe 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -c2b919b895bca9972c062ff679d9795e9f382ae6 +f7dd10b47071049b5d7abdafa822d3452adf1257 From 05772dd1527434b6ea5c30ec3bd7202e8c3768bc Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 16:59:39 +0000 Subject: [PATCH 054/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/DeleteMany.js | 44 +++++++++++-- snippets/functions/mongodb-crud/DeleteOne.js | 44 +++++++++++-- snippets/functions/mongodb-crud/InsertMany.js | 62 +++++++++++++------ snippets/functions/mongodb-crud/InsertOne.js | 56 ++++++++++++----- snippets/functions/mongodb-crud/Project.js | 40 +++++++++--- snippets/functions/mongodb-crud/UpdateMany.js | 59 +++++++++++++----- snippets/functions/mongodb-crud/UpdateOne.js | 17 ++--- .../functions/mongodb-crud/crud_DeleteMany.js | 51 --------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 --------------- snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 22 ------- .../functions/mongodb-crud/crud_InsertMany.js | 47 -------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 -------------- .../functions/mongodb-crud/crud_Project.js | 49 --------------- .../functions/mongodb-crud/crud_Replace.js | 55 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 60 ------------------ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ---------------- 19 files changed, 246 insertions(+), 554 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/DeleteMany.js b/snippets/functions/mongodb-crud/DeleteMany.js index 439e551..3cfb8f9 100644 --- a/snippets/functions/mongodb-crud/DeleteMany.js +++ b/snippets/functions/mongodb-crud/DeleteMany.js @@ -1,17 +1,51 @@ -exports = async function(args){ - console.log(JSON.stringify(args)); - +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection var dbName = "sample_supplies"; var collName = "sales"; + // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; try { - deleteResult = await collection.deleteMany(args); + deleteResult = await collection.deleteMany(deleteFilter); return deleteResult["deletedCount"]; } catch(err) { console.log("Failed to delete item: ", err.message); return { error: err.message }; } }; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/DeleteOne.js b/snippets/functions/mongodb-crud/DeleteOne.js index f6355f0..525dfc9 100644 --- a/snippets/functions/mongodb-crud/DeleteOne.js +++ b/snippets/functions/mongodb-crud/DeleteOne.js @@ -1,19 +1,51 @@ -exports = async function(deleteFilter){ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection var dbName = "sample_supplies"; var collName = "sales"; - // An example deleteFilter: - // { _id: ObjectId("123")} - + // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; try { deleteResult = await collection.deleteOne(deleteFilter); return deleteResult["deletedCount"]; - } catch(err) { console.log("Failed to delete item: ", err.message); return { error: err.message }; } }; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/InsertMany.js b/snippets/functions/mongodb-crud/InsertMany.js index bc71dd2..1c66e93 100644 --- a/snippets/functions/mongodb-crud/InsertMany.js +++ b/snippets/functions/mongodb-crud/InsertMany.js @@ -1,23 +1,47 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); try { - insertResult = await collection.insertMany(args); - console.log('insertResult ids:', insertResult.insertedIds); - console.log('insertResult length:', insertResult.insertedIds.length); - console.log('returning', JSON.stringify(insertResult)); - return insertResult; - - } catch(err) { - console.log("Failed to insert item(s): ", err.message); + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); return { error: err.message }; } -}; +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/InsertOne.js b/snippets/functions/mongodb-crud/InsertOne.js index 7a56008..5c66a83 100644 --- a/snippets/functions/mongodb-crud/InsertOne.js +++ b/snippets/functions/mongodb-crud/InsertOne.js @@ -1,21 +1,45 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - try { - // Execute an InsertOne in MongoDB - insertResult = await collection.insertOne(args); - return insertResult; - - } catch(err) { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { console.log("Failed to insert item: ", err.message); return { error: err.message }; } -}; +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/Project.js b/snippets/functions/mongodb-crud/Project.js index bf73baf..6a20fc7 100644 --- a/snippets/functions/mongodb-crud/Project.js +++ b/snippets/functions/mongodb-crud/Project.js @@ -1,23 +1,49 @@ -exports = async function(saleId, projection={}){ +exports = async function(changeEvent){ var serviceName = "mongodb-atlas"; var dbName = "sample_supplies"; var collName = "sales"; var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": new BSON.ObjectId(saleId) }; - // An example of the projection object that might be passed in: - /* const projection = { + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { _id:0, storeLocation:1, items: 1 - } */ + } + try { doc = await collection.findOne(query, projection); - console.log('found:', JSON.stringify(doc)); return doc; - } catch(err) { console.log("Failed to find item: ", err.message); return { error: err.message }; } }; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/UpdateMany.js b/snippets/functions/mongodb-crud/UpdateMany.js index 49d77eb..a95c038 100644 --- a/snippets/functions/mongodb-crud/UpdateMany.js +++ b/snippets/functions/mongodb-crud/UpdateMany.js @@ -1,31 +1,60 @@ -exports = async function(query, updateFilter){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); + // To test thia example, uncomment the following line: + // collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}) + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + // Example update filter: - /* const updateFilter = { + const updateFilter = { "$set": { - "storeId": storeId, + "storeLocation": "West Appleton" } }; - */ const options = { "upsert": false }; try { - updateResult = await collection.updateOne(query, updateFilter, options); - console.log(JSON.stringify(updateResult)); + updateResult = await collection.updateMany(query, updateFilter, options); return updateResult; } catch(err) { console.log("Failed to update item(s): ", err.message); return { error: err.message }; } -}; +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/UpdateOne.js b/snippets/functions/mongodb-crud/UpdateOne.js index 8353adf..7b7f8e2 100644 --- a/snippets/functions/mongodb-crud/UpdateOne.js +++ b/snippets/functions/mongodb-crud/UpdateOne.js @@ -4,6 +4,9 @@ exports = async function (changeEvent) { .db("sample_supplies") .collection("sales"); + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; const updateFields = { @@ -19,10 +22,7 @@ exports = async function (changeEvent) { } } -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +// In the Testing Console tab, paste the code below and click Run: /* exports({ _id: {_data: '62548f79e7f11292792497cc' }, @@ -38,7 +38,7 @@ exports({ coll: 'users' }, documentKey: { - userName: 'alice123', + storeLocation: 'East Appleton', _id: { "$oid": "62548f79e7f11292792497cc" } @@ -47,7 +47,8 @@ exports({ _id: { "$oid": "599af247bb69cd89961c986d" }, - userName: 'alice123', - name: 'Alice' + storeLocation: 'East Appleton', + couponUsed: false } -}*/ \ No newline at end of file +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index c65672e..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,22 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 5c66a83..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index d99b634..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,55 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const replacement = { - storeLocation: "East Appleton", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -} - -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } -}*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index a95c038..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,60 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "West Appleton" - } - }; - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 2491cf9aedf8cf1da405cf7b77fffb4d6c75927f Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 18:03:11 +0000 Subject: [PATCH 055/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 22 +++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 ++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 60 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 +++++++++++++++++ 10 files changed, 449 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..c65672e --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,22 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..5c66a83 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..10b8630 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + // await collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton","couponUsed":false}, {upsert:false}); + + const query = { _id: changeEvent._id._data }; + + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d" + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..a95c038 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,60 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "West Appleton" + } + }; + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From b4d74d78ba8f9977806fc2fdb05166f3991c0fce Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 18:03:12 +0000 Subject: [PATCH 056/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 62f402e8dece496056fc92795c5cc6719a6072dd Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 18:03:13 +0000 Subject: [PATCH 057/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 5ab484709f4bea043b91cfa2e192ccff24c44b03 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 18:03:23 +0000 Subject: [PATCH 058/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 9fababe..e67a72f 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -f7dd10b47071049b5d7abdafa822d3452adf1257 +4317c6e9b622a3714c504985c9e1e6d466d181f2 From b17e66844ec484852a6ae8278a46502b31970a11 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 18:03:25 +0000 Subject: [PATCH 059/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/Replace.js | 26 ++++---- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 22 ------- .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 -------------- .../functions/mongodb-crud/crud_Project.js | 49 --------------- .../functions/mongodb-crud/crud_Replace.js | 49 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 60 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ----------------- 13 files changed, 10 insertions(+), 488 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/Replace.js b/snippets/functions/mongodb-crud/Replace.js index d99b634..10b8630 100644 --- a/snippets/functions/mongodb-crud/Replace.js +++ b/snippets/functions/mongodb-crud/Replace.js @@ -4,7 +4,10 @@ exports = async function (changeEvent) { .db("sample_supplies") .collection("sales"); - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + // To test the above example, insert the following document into your collection: + // await collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton","couponUsed":false}, {upsert:false}); + + const query = { _id: changeEvent._id._data }; const replacement = { storeLocation: "East Appleton", @@ -19,12 +22,9 @@ exports = async function (changeEvent) { console.log("Failed to replace item: ", err.message); return { error: err.message }; } -} +}; -// To test the above example, insert the following document into your collection: -// {"_id":{"$oid":"62548f79e7f11292792497cc"},"storeLocation":"East Appleton","couponUsed":false} - -// Then, in the testing console paste the code below and click Run to test this mock change event against the example code +// In the Testing Console tab, paste the code below and click Run: /* exports({ _id: {_data: '62548f79e7f11292792497cc' }, @@ -40,16 +40,10 @@ exports({ coll: 'users' }, documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } + _id: "62548f79e7f11292792497cc" }, fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' + _id: "599af247bb69cd89961c986d" + storeLocation: 'East Appleton' } -}*/ \ No newline at end of file +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index c65672e..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,22 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 5c66a83..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 10b8630..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - // await collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton","couponUsed":false}, {upsert:false}); - - const query = { _id: changeEvent._id._data }; - - const replacement = { - storeLocation: "East Appleton", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d" - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index a95c038..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,60 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "West Appleton" - } - }; - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 24f97e07eef8f10f1c9f64a0ea7b178437641ef0 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 18:10:43 +0000 Subject: [PATCH 060/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 +++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 ++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 60 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 +++++++++++++++++ 10 files changed, 483 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..5c66a83 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..10b8630 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + // await collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton","couponUsed":false}, {upsert:false}); + + const query = { _id: changeEvent._id._data }; + + const replacement = { + storeLocation: "East Appleton", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d" + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..a95c038 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,60 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "West Appleton" + } + }; + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 140db0f03296d1062f8cfa9964d954906583223e Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 18:10:45 +0000 Subject: [PATCH 061/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 04eb82dfda34f240660449164f8590ef4616b73c Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 18:10:48 +0000 Subject: [PATCH 062/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 8ce8ff6ca081daf7056f2dd40573cc199c0a7141 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 18:10:54 +0000 Subject: [PATCH 063/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index e67a72f..ea9e89f 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -4317c6e9b622a3714c504985c9e1e6d466d181f2 +bbe93e3d26a0f6c6f7ca28c83340e064c68a458f From d85c5c8d5537bdffe8259aca4cf404c978c98337 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 18:10:56 +0000 Subject: [PATCH 064/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/FindOne.js | 40 ++++++++++++- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 56 ----------------- .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 -------------- .../functions/mongodb-crud/crud_Project.js | 49 --------------- .../functions/mongodb-crud/crud_Replace.js | 49 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 60 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ----------------- 13 files changed, 37 insertions(+), 509 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/FindOne.js b/snippets/functions/mongodb-crud/FindOne.js index c65672e..893012b 100644 --- a/snippets/functions/mongodb-crud/FindOne.js +++ b/snippets/functions/mongodb-crud/FindOne.js @@ -8,8 +8,11 @@ exports = async function(changeEvent){ // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const query = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; try { doc = await collection.findOne(query); @@ -19,4 +22,35 @@ exports = async function(changeEvent){ console.log("Failed to find item: ", err.message); return { error: err.message }; } -}; \ No newline at end of file +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 5c66a83..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 10b8630..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - // await collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton","couponUsed":false}, {upsert:false}); - - const query = { _id: changeEvent._id._data }; - - const replacement = { - storeLocation: "East Appleton", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d" - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index a95c038..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,60 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "West Appleton" - } - }; - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From d42779e1a5c8e484f69d49b02cda9e6de5c93bbb Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 18:11:02 +0000 Subject: [PATCH 065/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index ea9e89f..022106d 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -bbe93e3d26a0f6c6f7ca28c83340e064c68a458f +d85c5c8d5537bdffe8259aca4cf404c978c98337 From cf8c13e782ffa3dd9373968a2b02c7c7664574f6 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 19:18:52 +0000 Subject: [PATCH 066/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 +++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 ++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 60 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 +++++++++++++++++ 10 files changed, 483 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..5c66a83 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..8a6fd45 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..03fbaa7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,60 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "West Appleton" + } + }; + + const options = { "upsert": false }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From cba86dfcfbdcc7d363956deb331eacbcb23bcc6b Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 19:18:54 +0000 Subject: [PATCH 067/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 7e6cfdc832cf327b4b39b1c5a45afc79aeb49f30 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 19:18:57 +0000 Subject: [PATCH 068/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 95921349f70c385f87c17278d13940bbbceae1de Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 19:19:05 +0000 Subject: [PATCH 069/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/Replace.js | 10 ++-- snippets/functions/mongodb-crud/UpdateMany.js | 2 +- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 56 ----------------- .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 -------------- .../functions/mongodb-crud/crud_Project.js | 49 --------------- .../functions/mongodb-crud/crud_Replace.js | 49 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 60 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ----------------- 14 files changed, 6 insertions(+), 512 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/Replace.js b/snippets/functions/mongodb-crud/Replace.js index 10b8630..8a6fd45 100644 --- a/snippets/functions/mongodb-crud/Replace.js +++ b/snippets/functions/mongodb-crud/Replace.js @@ -5,12 +5,12 @@ exports = async function (changeEvent) { .collection("sales"); // To test the above example, insert the following document into your collection: - // await collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton","couponUsed":false}, {upsert:false}); - - const query = { _id: changeEvent._id._data }; + await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; const replacement = { - storeLocation: "East Appleton", + storeLocation: "Orangeville", couponUsed: false, }; @@ -43,7 +43,7 @@ exports({ _id: "62548f79e7f11292792497cc" }, fullDocument: { - _id: "599af247bb69cd89961c986d" + _id: "599af247bb69cd89961c986d", storeLocation: 'East Appleton' } })*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/UpdateMany.js b/snippets/functions/mongodb-crud/UpdateMany.js index a95c038..03fbaa7 100644 --- a/snippets/functions/mongodb-crud/UpdateMany.js +++ b/snippets/functions/mongodb-crud/UpdateMany.js @@ -5,7 +5,7 @@ exports = async function (changeEvent) { .collection("sales"); // To test thia example, uncomment the following line: - // collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}) + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) const query = { storeLocation: changeEvent.fullDocument.storeLocation }; diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 5c66a83..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 8a6fd45..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index 03fbaa7..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,60 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "West Appleton" - } - }; - - const options = { "upsert": false }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From d8bd0a3c81dc00c164c8d314532dd53003e8f5c1 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 19:19:07 +0000 Subject: [PATCH 070/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 022106d..afa9644 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -d85c5c8d5537bdffe8259aca4cf404c978c98337 +95921349f70c385f87c17278d13940bbbceae1de From d40f40462bcf37b9530130f7a728412c82b9c384 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:02:40 +0000 Subject: [PATCH 071/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 +++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 60 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 +++++++++++++++++ 10 files changed, 485 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..90c49ce --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"_id": changeEvent._id._data, + "storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..b0661cb --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,60 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "West Appleton" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 4beaccafca0616eda44acf86aaad505d67b92038 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:02:43 +0000 Subject: [PATCH 072/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From f119ae41ec2e46017b0086756c5c3715d082b89d Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:02:45 +0000 Subject: [PATCH 073/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 6ea72f385499b483746af75d74832f81282084e3 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:02:53 +0000 Subject: [PATCH 074/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/InsertOne.js | 4 +- snippets/functions/mongodb-crud/Replace.js | 2 +- snippets/functions/mongodb-crud/UpdateMany.js | 2 +- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 56 ----------------- .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 47 --------------- .../functions/mongodb-crud/crud_Project.js | 49 --------------- .../functions/mongodb-crud/crud_Replace.js | 49 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 60 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ----------------- 15 files changed, 5 insertions(+), 511 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/InsertOne.js b/snippets/functions/mongodb-crud/InsertOne.js index 5c66a83..90c49ce 100644 --- a/snippets/functions/mongodb-crud/InsertOne.js +++ b/snippets/functions/mongodb-crud/InsertOne.js @@ -5,7 +5,9 @@ exports = async function (changeEvent) { .collection("sales"); try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); + var result = await collection.insertOne({"_id": changeEvent._id._data, + "storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); return result; } catch (err) { console.log("Failed to insert item: ", err.message); diff --git a/snippets/functions/mongodb-crud/Replace.js b/snippets/functions/mongodb-crud/Replace.js index 8a6fd45..227493d 100644 --- a/snippets/functions/mongodb-crud/Replace.js +++ b/snippets/functions/mongodb-crud/Replace.js @@ -5,7 +5,7 @@ exports = async function (changeEvent) { .collection("sales"); // To test the above example, insert the following document into your collection: - await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); const query = { storeLocation: changeEvent.fullDocument.storeLocation }; diff --git a/snippets/functions/mongodb-crud/UpdateMany.js b/snippets/functions/mongodb-crud/UpdateMany.js index 03fbaa7..b0661cb 100644 --- a/snippets/functions/mongodb-crud/UpdateMany.js +++ b/snippets/functions/mongodb-crud/UpdateMany.js @@ -16,7 +16,7 @@ exports = async function (changeEvent) { } }; - const options = { "upsert": false }; + const options = { "upsert": true }; try { updateResult = await collection.updateMany(query, updateFilter, options); diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index 90c49ce..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"_id": changeEvent._id._data, - "storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index b0661cb..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,60 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "West Appleton" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 5819fb3cf2c54f915e32722d22d7bcb414ac4db2 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:02:54 +0000 Subject: [PATCH 075/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index afa9644..e2cdfbb 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -95921349f70c385f87c17278d13940bbbceae1de +6ea72f385499b483746af75d74832f81282084e3 From 1cf7ffc9f7388ec673ad371d3a17b649f0d0bab8 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:02:56 +0000 Subject: [PATCH 076/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index e2cdfbb..3033630 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -6ea72f385499b483746af75d74832f81282084e3 +5819fb3cf2c54f915e32722d22d7bcb414ac4db2 From 1b83be1bb264173c93b86a54810ac9a9eda14408 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:02:58 +0000 Subject: [PATCH 077/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 3033630..7dd16b5 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -5819fb3cf2c54f915e32722d22d7bcb414ac4db2 +1cf7ffc9f7388ec673ad371d3a17b649f0d0bab8 From 0770f5bc2b2c6ba05c48c365c6a196326596008c Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:09:36 +0000 Subject: [PATCH 078/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 +++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 42 +++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 60 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 +++++++++++++++++ 10 files changed, 480 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..c724d01 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,42 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..b0661cb --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,60 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "West Appleton" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 523eff5387694201de2d8ca14730e36f42a537ee Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:09:37 +0000 Subject: [PATCH 079/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 9cc9bacf23fc1bff7dece1c90af8198a87fd4b6e Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:09:38 +0000 Subject: [PATCH 080/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From cf497bdd182f67c3a51fd4d9fd92f13e2ab74d1b Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:09:49 +0000 Subject: [PATCH 081/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 7dd16b5..4519cda 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -1cf7ffc9f7388ec673ad371d3a17b649f0d0bab8 +199fe05d6375e950a9b770bf88560edaee5d6a11 From 64b280276bde4613b7f89a73dcadd8a6d4ef92db Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:09:50 +0000 Subject: [PATCH 082/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/InsertOne.js | 11 +--- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 56 ----------------- .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 42 ------------- .../functions/mongodb-crud/crud_Project.js | 49 --------------- .../functions/mongodb-crud/crud_Replace.js | 49 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 60 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ----------------- 13 files changed, 3 insertions(+), 511 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/InsertOne.js b/snippets/functions/mongodb-crud/InsertOne.js index 90c49ce..c724d01 100644 --- a/snippets/functions/mongodb-crud/InsertOne.js +++ b/snippets/functions/mongodb-crud/InsertOne.js @@ -5,8 +5,7 @@ exports = async function (changeEvent) { .collection("sales"); try { - var result = await collection.insertOne({"_id": changeEvent._id._data, - "storeLocation":changeEvent.fullDocument.storeLocation, + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}); return result; } catch (err) { @@ -32,14 +31,10 @@ exports({ }, documentKey: { storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } + _id: "62548f79e7f11292792497cc" }, fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, + _id: "599af247bb69cd89961c986d", storeLocation: 'East Appleton', items: ["envelopes"] } diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index c724d01..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,42 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index b0661cb..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,60 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "West Appleton" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 1a482c9285423181a7b0fa6db7c8a5ec9d1e2977 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:18:58 +0000 Subject: [PATCH 083/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 21 +++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 +++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 ++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 42 +++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 61 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++ 10 files changed, 481 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..6ffc940 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,21 @@ +exports = async function(args){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + try { + docs = await collection.find(args); + console.log(JSON.stringify(docs)); + return docs; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..c724d01 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,42 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..cb931e4 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,61 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From e0a7a6c606ba4383a3a8ee9a7781608780019bd6 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:18:59 +0000 Subject: [PATCH 084/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From b90683358d7faf879c75187219eb5a5b59a247b3 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:19:01 +0000 Subject: [PATCH 085/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 9935bfb5b8bf1d99a6ceba1c29910c226aea7c3d Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:19:09 +0000 Subject: [PATCH 086/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/UpdateMany.js | 3 +- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 21 ------- .../functions/mongodb-crud/crud_FindOne.js | 56 ----------------- .../functions/mongodb-crud/crud_InsertMany.js | 47 -------------- .../functions/mongodb-crud/crud_InsertOne.js | 42 ------------- .../functions/mongodb-crud/crud_Project.js | 49 --------------- .../functions/mongodb-crud/crud_Replace.js | 49 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 61 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ---------------- 13 files changed, 2 insertions(+), 505 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/UpdateMany.js b/snippets/functions/mongodb-crud/UpdateMany.js index b0661cb..cb931e4 100644 --- a/snippets/functions/mongodb-crud/UpdateMany.js +++ b/snippets/functions/mongodb-crud/UpdateMany.js @@ -12,7 +12,8 @@ exports = async function (changeEvent) { // Example update filter: const updateFilter = { "$set": { - "storeLocation": "West Appleton" + "storeLocation": "Langley", + "purchaseMethod" : "credit" } }; diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 6ffc940..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,21 +0,0 @@ -exports = async function(args){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index c724d01..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,42 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index cb931e4..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,61 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From a5e52ef7496c8b9f6d99205ac143f09437f2baf8 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:19:11 +0000 Subject: [PATCH 087/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 4519cda..df72eb0 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -199fe05d6375e950a9b770bf88560edaee5d6a11 +9935bfb5b8bf1d99a6ceba1c29910c226aea7c3d From 7632f789153e4718dfc327ebafd4e1cc118b2723 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:19:13 +0000 Subject: [PATCH 088/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index df72eb0..68038c0 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -9935bfb5b8bf1d99a6ceba1c29910c226aea7c3d +a5e52ef7496c8b9f6d99205ac143f09437f2baf8 From 802100347ef3a161852a111ff4baa2c17721ef81 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:27:49 +0000 Subject: [PATCH 089/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 +++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 ++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 42 +++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 61 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++ 10 files changed, 509 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..1b03628 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + await collection.updateOne({_id:changeEvent.fullDocument._id, "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + try { + findResults = await collection.find({_id: changeEvent.fullDocument._id}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..c724d01 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,42 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..cb931e4 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,61 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From bd0211b5d79ce19759c905741ef5c14d87b31c42 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:27:50 +0000 Subject: [PATCH 090/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From dd488c957ae2b327f64c4da64b44d4b4948fd942 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:27:51 +0000 Subject: [PATCH 091/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 8f64ee174ce29e8b1527b04f06349251c5053f19 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:28:01 +0000 Subject: [PATCH 092/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/Find.js | 40 ++++++++++-- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 --------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ----------------- .../functions/mongodb-crud/crud_InsertMany.js | 47 -------------- .../functions/mongodb-crud/crud_InsertOne.js | 42 ------------- .../functions/mongodb-crud/crud_Project.js | 49 --------------- .../functions/mongodb-crud/crud_Replace.js | 49 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 61 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ---------------- 13 files changed, 34 insertions(+), 538 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/Find.js b/snippets/functions/mongodb-crud/Find.js index 6ffc940..1b03628 100644 --- a/snippets/functions/mongodb-crud/Find.js +++ b/snippets/functions/mongodb-crud/Find.js @@ -1,4 +1,4 @@ -exports = async function(args){ +exports = async function(changeEvent){ // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) var serviceName = "mongodb-atlas"; @@ -9,13 +9,41 @@ exports = async function(args){ // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - try { - docs = await collection.find(args); - console.log(JSON.stringify(docs)); - return docs; + // To test this example, uncomment the following line: + await collection.updateOne({_id:changeEvent.fullDocument._id, "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + try { + findResults = await collection.find({_id: changeEvent.fullDocument._id}); + return findResults; } catch(err) { console.log("Failed to find item: ", err.message); return { error: err.message }; } -} \ No newline at end of file +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index 1b03628..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - await collection.updateOne({_id:changeEvent.fullDocument._id, "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - try { - findResults = await collection.find({_id: changeEvent.fullDocument._id}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index c724d01..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,42 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index cb931e4..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,61 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From d6804dc0a7b3f60b7560a327da85303445250625 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:28:03 +0000 Subject: [PATCH 093/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 68038c0..6723cc2 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -a5e52ef7496c8b9f6d99205ac143f09437f2baf8 +8f64ee174ce29e8b1527b04f06349251c5053f19 From 63c9005c7e6b267f065d33f91cdf3631cfaad465 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:34:40 +0000 Subject: [PATCH 094/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 +++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 ++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 42 +++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 +++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 61 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++ 10 files changed, 509 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..c3c3842 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..c724d01 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,42 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..cb931e4 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,61 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 96b30ecc1adf2f289490e9ea58faf0d6b709b48e Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:34:42 +0000 Subject: [PATCH 095/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 6f048195dba6cd4bb49fe08c80cffe7a5142a93f Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:34:44 +0000 Subject: [PATCH 096/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 1d7cc44e99075db372b38e6739026c9af945e16d Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:34:53 +0000 Subject: [PATCH 097/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 6723cc2..c3db5df 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -8f64ee174ce29e8b1527b04f06349251c5053f19 +d7af8f77b682608c79fd113418b9856edc910029 From 16346a45dcbb7eff909d6e14f4d5d0396ca64c84 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:34:54 +0000 Subject: [PATCH 098/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/Find.js | 4 +- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 --------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ----------------- .../functions/mongodb-crud/crud_InsertMany.js | 47 -------------- .../functions/mongodb-crud/crud_InsertOne.js | 42 ------------- .../functions/mongodb-crud/crud_Project.js | 49 --------------- .../functions/mongodb-crud/crud_Replace.js | 49 --------------- .../functions/mongodb-crud/crud_UpdateMany.js | 61 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ---------------- 13 files changed, 2 insertions(+), 534 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/Find.js b/snippets/functions/mongodb-crud/Find.js index 1b03628..c3c3842 100644 --- a/snippets/functions/mongodb-crud/Find.js +++ b/snippets/functions/mongodb-crud/Find.js @@ -10,10 +10,10 @@ exports = async function(changeEvent){ var collection = context.services.get(serviceName).db(dbName).collection(collName); // To test this example, uncomment the following line: - await collection.updateOne({_id:changeEvent.fullDocument._id, "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); try { - findResults = await collection.find({_id: changeEvent.fullDocument._id}); + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); return findResults; } catch(err) { console.log("Failed to find item: ", err.message); diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index c3c3842..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index c724d01..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,42 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index cb931e4..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,61 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From c3b5ea4e185eba9d7499a8ec0277c5698ad37373 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:34:55 +0000 Subject: [PATCH 099/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index c3db5df..659a868 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -d7af8f77b682608c79fd113418b9856edc910029 +16346a45dcbb7eff909d6e14f4d5d0396ca64c84 From 68397012705a47131f42001cbd3f9a4ce78d9ea9 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:37:04 +0000 Subject: [PATCH 100/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 +++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 51 +++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 42 ++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 505 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..525dfc9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..c724d01 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,42 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From c77d8f7b9c20dff677fcb32a7fc1c41beb37f8be Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:37:06 +0000 Subject: [PATCH 101/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 23e3e1897477f7fe3c341a98f94bf73597ab3881 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:37:09 +0000 Subject: [PATCH 102/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 4f274d26bc25edf7444a456e879a0dbbae5e8839 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:37:17 +0000 Subject: [PATCH 103/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 659a868..021357a 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -16346a45dcbb7eff909d6e14f4d5d0396ca64c84 +4df3941aecc3443e6b8b9a17c1f106443cef3bd4 From 11e8cc71a0c85ce09a7644395d17ab710e84b7f9 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:37:18 +0000 Subject: [PATCH 104/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/Find.js | 2 +- snippets/functions/mongodb-crud/UpdateMany.js | 8 +-- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ----------------- .../functions/mongodb-crud/crud_DeleteOne.js | 51 ----------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 42 -------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 14 files changed, 3 insertions(+), 535 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/Find.js b/snippets/functions/mongodb-crud/Find.js index c3c3842..e46a93d 100644 --- a/snippets/functions/mongodb-crud/Find.js +++ b/snippets/functions/mongodb-crud/Find.js @@ -10,7 +10,7 @@ exports = async function(changeEvent){ var collection = context.services.get(serviceName).db(dbName).collection(collName); // To test this example, uncomment the following line: - await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); try { findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); diff --git a/snippets/functions/mongodb-crud/UpdateMany.js b/snippets/functions/mongodb-crud/UpdateMany.js index cb931e4..f171239 100644 --- a/snippets/functions/mongodb-crud/UpdateMany.js +++ b/snippets/functions/mongodb-crud/UpdateMany.js @@ -46,14 +46,10 @@ exports({ }, documentKey: { storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } + _id: "62548f79e7f11292792497cc" }, fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, + _id: "599af247bb69cd89961c986d", storeLocation: 'East Appleton', couponUsed: false } diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 525dfc9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index c724d01..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,42 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 2a5ccbef595ecd32f95261ebcc33b66c7fc2be82 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:37:19 +0000 Subject: [PATCH 105/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 021357a..b036115 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -4df3941aecc3443e6b8b9a17c1f106443cef3bd4 +11e8cc71a0c85ce09a7644395d17ab710e84b7f9 From 808e67e9bdc00811e06e5455b861d3ec81eb55a5 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:37:21 +0000 Subject: [PATCH 106/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index b036115..0605ed2 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -11e8cc71a0c85ce09a7644395d17ab710e84b7f9 +2a5ccbef595ecd32f95261ebcc33b66c7fc2be82 From 534f2d92e6f873fd68192682741e90b822a5c281 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:40:51 +0000 Subject: [PATCH 107/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 +++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 47 +++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 42 ++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 501 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..6f9ef3c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,47 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..c724d01 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,42 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 59641f2353fe7fdb4a3c003ccaf596504ea45101 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:40:53 +0000 Subject: [PATCH 108/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From cfebd15549952099b80fb9424ebefab915871862 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:40:54 +0000 Subject: [PATCH 109/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From dd9405d18f7dcb5eab62affb45d3a35006d36d86 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:41:01 +0000 Subject: [PATCH 110/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/DeleteOne.js | 10 +--- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ----------------- .../functions/mongodb-crud/crud_DeleteOne.js | 47 --------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 42 -------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 13 files changed, 3 insertions(+), 531 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/DeleteOne.js b/snippets/functions/mongodb-crud/DeleteOne.js index 525dfc9..6f9ef3c 100644 --- a/snippets/functions/mongodb-crud/DeleteOne.js +++ b/snippets/functions/mongodb-crud/DeleteOne.js @@ -9,7 +9,7 @@ exports = async function(changeEvent){ // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - const deleteFilter = { "_id": new BSON.ObjectId(changeEvent._id._data) }; + const deleteFilter = { "_id": changeEvent._id._data }; try { deleteResult = await collection.deleteOne(deleteFilter); return deleteResult["deletedCount"]; @@ -36,14 +36,10 @@ exports({ }, documentKey: { storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } + _id: "62548f79e7f11292792497cc" }, fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, + _id: "599af247bb69cd89961c986d", storeLocation: 'East Appleton', couponUsed: false } diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 3cfb8f9..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 6f9ef3c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index c724d01..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,42 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From f086d04a2a53853c91219d0d7cde700fd69f9528 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:41:04 +0000 Subject: [PATCH 111/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 0605ed2..05a1d16 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -2a5ccbef595ecd32f95261ebcc33b66c7fc2be82 +dd9405d18f7dcb5eab62affb45d3a35006d36d86 From 62081c581296c1409cc053d7ced205bb58d36969 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:41:06 +0000 Subject: [PATCH 112/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 05a1d16..cd52366 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -dd9405d18f7dcb5eab62affb45d3a35006d36d86 +f086d04a2a53853c91219d0d7cde700fd69f9528 From 732d7aab326ad47f8ba243625b5e2bc4261f1cfb Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:41:08 +0000 Subject: [PATCH 113/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index cd52366..a73b5a0 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -f086d04a2a53853c91219d0d7cde700fd69f9528 +62081c581296c1409cc053d7ced205bb58d36969 From bdab79fe91a9f443d9142d67f23a89fea8016246 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:42:19 +0000 Subject: [PATCH 114/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 +++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 42 ++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..3cfb8f9 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..c724d01 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,42 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 4c0ca5e265171e4f2822c7abf2bc825b04f14386 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:42:21 +0000 Subject: [PATCH 115/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 1908423e8a17e694ebdd6e2385c7a65c18925208 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:42:23 +0000 Subject: [PATCH 116/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 037d24e117676d48d06844754922b19175586ef8 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:42:30 +0000 Subject: [PATCH 117/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index a73b5a0..3caea7c 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -62081c581296c1409cc053d7ced205bb58d36969 +e7f2265f3489d833d09f4b5094c33fd8a6c573c2 From 5bfcbdf40dc7b990b143f248486c2fb94b2c34ed Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:42:33 +0000 Subject: [PATCH 118/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 3caea7c..105736b 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -e7f2265f3489d833d09f4b5094c33fd8a6c573c2 +037d24e117676d48d06844754922b19175586ef8 From 47df1f8eaebd47297920851b0850db4cd41e8922 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:42:36 +0000 Subject: [PATCH 119/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 105736b..2f3760b 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -037d24e117676d48d06844754922b19175586ef8 +5bfcbdf40dc7b990b143f248486c2fb94b2c34ed From 6ea5d5f3ebdb012425821797b25623f213e1f482 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:45:04 +0000 Subject: [PATCH 120/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 +++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 42 ++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..e3a3a45 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + let deleteFilter; + + if (changeEvent == null) deleteFilter = {}; + else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..c724d01 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,42 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From c03fd8e9d3834c3920e11180fe615549ce1e5877 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:45:06 +0000 Subject: [PATCH 121/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 701bbc22fd1f5fd76fd047f0c59c136982e666da Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:45:07 +0000 Subject: [PATCH 122/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 8c3e60f465921c70fc6cafc02027753e000fb1cc Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:45:16 +0000 Subject: [PATCH 123/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 2f3760b..7dc43ce 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -5bfcbdf40dc7b990b143f248486c2fb94b2c34ed +c590cdc464d3d8b5b6b5bd2cf434e4fdd02377de From c508b05fa9f7cce06bcc510ef26664ac031d12c0 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:45:17 +0000 Subject: [PATCH 124/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 7dc43ce..d13d20d 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -c590cdc464d3d8b5b6b5bd2cf434e4fdd02377de +8c3e60f465921c70fc6cafc02027753e000fb1cc From 0f8a4c2739d57eb9fafbac631506e3e93043ccd6 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:45:18 +0000 Subject: [PATCH 125/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/DeleteMany.js | 14 ++--- snippets/functions/mongodb-crud/DeleteOne.js | 2 + .../functions/mongodb-crud/crud_DeleteMany.js | 51 ----------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 42 -------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 14 files changed, 9 insertions(+), 533 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/DeleteMany.js b/snippets/functions/mongodb-crud/DeleteMany.js index 3cfb8f9..e3a3a45 100644 --- a/snippets/functions/mongodb-crud/DeleteMany.js +++ b/snippets/functions/mongodb-crud/DeleteMany.js @@ -9,7 +9,11 @@ exports = async function(changeEvent){ // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + let deleteFilter; + + if (changeEvent == null) deleteFilter = {}; + else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + try { deleteResult = await collection.deleteMany(deleteFilter); return deleteResult["deletedCount"]; @@ -36,14 +40,10 @@ exports({ }, documentKey: { storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } + _id: "62548f79e7f11292792497cc" }, fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, + _id: "599af247bb69cd89961c986d", storeLocation: 'East Appleton', couponUsed: false } diff --git a/snippets/functions/mongodb-crud/DeleteOne.js b/snippets/functions/mongodb-crud/DeleteOne.js index 6f9ef3c..56afd1c 100644 --- a/snippets/functions/mongodb-crud/DeleteOne.js +++ b/snippets/functions/mongodb-crud/DeleteOne.js @@ -1,4 +1,6 @@ exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) var serviceName = "mongodb-atlas"; diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index e3a3a45..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - let deleteFilter; - - if (changeEvent == null) deleteFilter = {}; - else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index c724d01..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,42 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From e3e6931fabb3e6f47fee9141108d454275aa58ac Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:47:56 +0000 Subject: [PATCH 126/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 +++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 506 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..e3a3a45 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + let deleteFilter; + + if (changeEvent == null) deleteFilter = {}; + else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..7b7f8e2 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 40ed59b80374ec1bbd1a1876a527dcd9020133d6 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:47:57 +0000 Subject: [PATCH 127/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 32558efacf7b688aa69029b1ae48229a27906318 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:47:59 +0000 Subject: [PATCH 128/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 465336b5578b8776ec71f2fbdcc5a830dfedd8b8 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:48:05 +0000 Subject: [PATCH 129/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/InsertOne.js | 3 + .../functions/mongodb-crud/crud_DeleteMany.js | 51 ----------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 13 files changed, 3 insertions(+), 529 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/InsertOne.js b/snippets/functions/mongodb-crud/InsertOne.js index c724d01..f5df3d8 100644 --- a/snippets/functions/mongodb-crud/InsertOne.js +++ b/snippets/functions/mongodb-crud/InsertOne.js @@ -1,4 +1,7 @@ exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + var collection = context.services .get("mongodb-atlas") .db("sample_supplies") diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index e3a3a45..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - let deleteFilter; - - if (changeEvent == null) deleteFilter = {}; - else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 7b7f8e2..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 8a9dc5163f18a7a64e6224e2b96b59c556519d9e Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:48:07 +0000 Subject: [PATCH 130/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index d13d20d..eb1c82c 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -8c3e60f465921c70fc6cafc02027753e000fb1cc +465336b5578b8776ec71f2fbdcc5a830dfedd8b8 From 2454f3080415afaf9dfd78c60aded230deccf9cd Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:48:10 +0000 Subject: [PATCH 131/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index eb1c82c..bebe960 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -465336b5578b8776ec71f2fbdcc5a830dfedd8b8 +8a9dc5163f18a7a64e6224e2b96b59c556519d9e From 0feabf4098f1817878a73fd8f329f2a372e080b4 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:58:08 +0000 Subject: [PATCH 132/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 +++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 50 ++++++++++++++++ 10 files changed, 502 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..e3a3a45 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + let deleteFilter; + + if (changeEvent == null) deleteFilter = {}; + else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..ae5ed63 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,50 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.insertOne({"_id":"62548f79e7f11292792497cc","storeLocation":"East Appleton","couponUsed":false}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + return await collection.updateOne(query, updateFields); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From bc253b26e5049837af075a35e12e879d026a4b1e Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:58:10 +0000 Subject: [PATCH 133/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From ff578bcc3b0ad8d8bb08c3f14262a07e537a0eef Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 20:58:11 +0000 Subject: [PATCH 134/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 73acc18204acce131b661d6d0dcf06efcb091357 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:58:19 +0000 Subject: [PATCH 135/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index bebe960..c63f448 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -8a9dc5163f18a7a64e6224e2b96b59c556519d9e +16513596f21cc255257b42c23e7c75b180e6944a From cc8ac5ea7fa4a5fdc0f206b3ec68742763c9cb15 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:58:20 +0000 Subject: [PATCH 136/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/UpdateOne.js | 12 ++-- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ----------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 50 ---------------- 13 files changed, 4 insertions(+), 533 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/UpdateOne.js b/snippets/functions/mongodb-crud/UpdateOne.js index 7b7f8e2..ae5ed63 100644 --- a/snippets/functions/mongodb-crud/UpdateOne.js +++ b/snippets/functions/mongodb-crud/UpdateOne.js @@ -5,9 +5,9 @@ exports = async function (changeEvent) { .collection("sales"); // To test this example, uncomment the following line: - // collection.insertOne({"_id": new BSON.ObjectId("62548f79e7f11292792497cc"),"storeLocation":"East Appleton","couponUsed":false}); + // await collection.insertOne({"_id":"62548f79e7f11292792497cc","storeLocation":"East Appleton","couponUsed":false}); - const query = { _id: new BSON.ObjectId(changeEvent._id._data) }; + const query = { _id: changeEvent._id._data }; const updateFields = { storeLocation: "West Appleton", @@ -39,14 +39,10 @@ exports({ }, documentKey: { storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } + _id: "62548f79e7f11292792497cc" }, fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, + _id: "599af247bb69cd89961c986d", storeLocation: 'East Appleton', couponUsed: false } diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index e3a3a45..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - let deleteFilter; - - if (changeEvent == null) deleteFilter = {}; - else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index ae5ed63..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,50 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.insertOne({"_id":"62548f79e7f11292792497cc","storeLocation":"East Appleton","couponUsed":false}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - return await collection.updateOne(query, updateFields); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 66f48163b6727d47c4afdbe74225af09b608a40a Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 20:58:21 +0000 Subject: [PATCH 137/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index c63f448..da762c5 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -16513596f21cc255257b42c23e7c75b180e6944a +cc8ac5ea7fa4a5fdc0f206b3ec68742763c9cb15 From 062ab0788fb3d7cbd8e12cc1be1ab5e9d4a35d0d Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:04:11 +0000 Subject: [PATCH 138/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 +++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 51 +++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..e3a3a45 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + let deleteFilter; + + if (changeEvent == null) deleteFilter = {}; + else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..531a831 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,51 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From ba6a566302f6946e7ec03c3b2bdf2b43dfe96fc8 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:04:13 +0000 Subject: [PATCH 139/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 977e57b5e7c3825f48fad74494f844af33c4b845 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:04:14 +0000 Subject: [PATCH 140/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From c8d1ba7d6895f5d8097243c5e3f85047451492b5 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:04:22 +0000 Subject: [PATCH 141/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index da762c5..061b303 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -cc8ac5ea7fa4a5fdc0f206b3ec68742763c9cb15 +687fa2e737812609ac5917b40a3ee9f2e207d2e5 From a6362f991ad6818738a3a645a63cb79fd171c32b Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:04:24 +0000 Subject: [PATCH 142/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 061b303..636b397 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -687fa2e737812609ac5917b40a3ee9f2e207d2e5 +c8d1ba7d6895f5d8097243c5e3f85047451492b5 From 52a8f503569b4b4d901d002d4e3a1fb83a5213c0 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:04:25 +0000 Subject: [PATCH 143/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/UpdateOne.js | 9 +-- .../functions/mongodb-crud/crud_DeleteMany.js | 51 ----------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 51 ----------------- 13 files changed, 5 insertions(+), 530 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/UpdateOne.js b/snippets/functions/mongodb-crud/UpdateOne.js index ae5ed63..531a831 100644 --- a/snippets/functions/mongodb-crud/UpdateOne.js +++ b/snippets/functions/mongodb-crud/UpdateOne.js @@ -4,8 +4,8 @@ exports = async function (changeEvent) { .db("sample_supplies") .collection("sales"); - // To test this example, uncomment the following line: - // await collection.insertOne({"_id":"62548f79e7f11292792497cc","storeLocation":"East Appleton","couponUsed":false}); + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); const query = { _id: changeEvent._id._data }; @@ -15,7 +15,8 @@ exports = async function (changeEvent) { }; try { - return await collection.updateOne(query, updateFields); + await collection.updateOne(query, updateFields); + return await collection.findOne(query); } catch (err) { console.log("Failed to update item: ", err.message); return { error: err.message }; @@ -42,7 +43,7 @@ exports({ _id: "62548f79e7f11292792497cc" }, fullDocument: { - _id: "599af247bb69cd89961c986d", + _id: "62548f79e7f11292792497cc", storeLocation: 'East Appleton', couponUsed: false } diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index e3a3a45..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - let deleteFilter; - - if (changeEvent == null) deleteFilter = {}; - else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index 531a831..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 7e8fb7ceee8ee6df1d83cdc15828f70c8bc1b045 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:12:07 +0000 Subject: [PATCH 144/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 51 +++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 506 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..e3a3a45 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,51 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + let deleteFilter; + + if (changeEvent == null) deleteFilter = {}; + else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..aeb1e2a --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 518f3e6c4fb091b032f47ee1da638fa5b96fb740 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:12:09 +0000 Subject: [PATCH 145/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 7c99b1b4a4e5fd3d1e4002a327f8fd3d6ff7f605 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:12:12 +0000 Subject: [PATCH 146/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 90a8492561f1211a003a93590c33d01892864499 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:12:20 +0000 Subject: [PATCH 147/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/UpdateOne.js | 3 + .../functions/mongodb-crud/crud_DeleteMany.js | 51 ----------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 13 files changed, 3 insertions(+), 529 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/UpdateOne.js b/snippets/functions/mongodb-crud/UpdateOne.js index 531a831..aeb1e2a 100644 --- a/snippets/functions/mongodb-crud/UpdateOne.js +++ b/snippets/functions/mongodb-crud/UpdateOne.js @@ -1,4 +1,7 @@ exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + var collection = context.services .get("mongodb-atlas") .db("sample_supplies") diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index e3a3a45..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,51 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - let deleteFilter; - - if (changeEvent == null) deleteFilter = {}; - else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index aeb1e2a..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 4feac428adeae977d474ecc649c72d01f60e445c Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:12:21 +0000 Subject: [PATCH 148/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 636b397..d03cdb8 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -c8d1ba7d6895f5d8097243c5e3f85047451492b5 +90a8492561f1211a003a93590c33d01892864499 From c2747b5daad51d43a3a92fc0782222c16afddfee Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:12:23 +0000 Subject: [PATCH 149/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index d03cdb8..73d3e69 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -90a8492561f1211a003a93590c33d01892864499 +4feac428adeae977d474ecc649c72d01f60e445c From 9c57369ddbff083b2da741e9c76f800d1ef2edb8 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:18:22 +0000 Subject: [PATCH 150/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 52 +++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 507 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..bb1be64 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,52 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + let deleteFilter; + + // Not passing in a changeEvent will delete **all** documents!! + if (changeEvent == {}) deleteFilter = {}; + else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..aeb1e2a --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From a956c27d125a5008952fb9ab3e67478155bb3cbb Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:18:24 +0000 Subject: [PATCH 151/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 4ca16effa52ccf6b2365ad2f29db4fc7c2841296 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:18:25 +0000 Subject: [PATCH 152/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 43c6e7cd460336290196c5dd0e6510003f1b7a05 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:18:35 +0000 Subject: [PATCH 153/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/DeleteMany.js | 5 +- .../functions/mongodb-crud/crud_DeleteMany.js | 52 ----------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 13 files changed, 3 insertions(+), 532 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/DeleteMany.js b/snippets/functions/mongodb-crud/DeleteMany.js index e3a3a45..bb1be64 100644 --- a/snippets/functions/mongodb-crud/DeleteMany.js +++ b/snippets/functions/mongodb-crud/DeleteMany.js @@ -10,8 +10,9 @@ exports = async function(changeEvent){ var collection = context.services.get(serviceName).db(dbName).collection(collName); let deleteFilter; - - if (changeEvent == null) deleteFilter = {}; + + // Not passing in a changeEvent will delete **all** documents!! + if (changeEvent == {}) deleteFilter = {}; else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; try { diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index bb1be64..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,52 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - let deleteFilter; - - // Not passing in a changeEvent will delete **all** documents!! - if (changeEvent == {}) deleteFilter = {}; - else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index aeb1e2a..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From c20cba4df1397e2382066ca3ae1ea1062145554f Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:18:35 +0000 Subject: [PATCH 154/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 73d3e69..4ecad39 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -4feac428adeae977d474ecc649c72d01f60e445c +43c6e7cd460336290196c5dd0e6510003f1b7a05 From 7e9f978732d67b1e2ac2b4fa852352ec7d042035 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:18:39 +0000 Subject: [PATCH 155/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 4ecad39..d8abfe8 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -43c6e7cd460336290196c5dd0e6510003f1b7a05 +c20cba4df1397e2382066ca3ae1ea1062145554f From 4aaf0e87db0d72f28aff1aee16683e92a19ee459 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:19:08 +0000 Subject: [PATCH 156/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..532481d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,48 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..aeb1e2a --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 0c354523726cef4cf8b05d317c26d442253c36fe Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:19:09 +0000 Subject: [PATCH 157/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From bb5e5a7d10fe70f41b0fd31240161233ec92a101 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Mon, 24 Jun 2024 21:19:10 +0000 Subject: [PATCH 158/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From c509345406d4c955f42881769f06215323bfec95 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:19:18 +0000 Subject: [PATCH 159/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/DeleteMany.js | 6 +- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 13 files changed, 1 insertion(+), 531 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/DeleteMany.js b/snippets/functions/mongodb-crud/DeleteMany.js index bb1be64..532481d 100644 --- a/snippets/functions/mongodb-crud/DeleteMany.js +++ b/snippets/functions/mongodb-crud/DeleteMany.js @@ -9,11 +9,7 @@ exports = async function(changeEvent){ // Get a collection from the context var collection = context.services.get(serviceName).db(dbName).collection(collName); - let deleteFilter; - - // Not passing in a changeEvent will delete **all** documents!! - if (changeEvent == {}) deleteFilter = {}; - else deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; try { deleteResult = await collection.deleteMany(deleteFilter); diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 532481d..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,48 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index aeb1e2a..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 9e15663f210cd6271d4b9f7ed5f8b71d93499aa5 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:19:20 +0000 Subject: [PATCH 160/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index d8abfe8..366005e 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -c20cba4df1397e2382066ca3ae1ea1062145554f +c509345406d4c955f42881769f06215323bfec95 From c32f16f4ac73787a322b274dd00a8918a0926894 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:19:21 +0000 Subject: [PATCH 161/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 366005e..a9ac721 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -c509345406d4c955f42881769f06215323bfec95 +9e15663f210cd6271d4b9f7ed5f8b71d93499aa5 From 9ac01f8e29244e8f848e5db4d207fe22a36abca0 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Mon, 24 Jun 2024 14:19:51 -0700 Subject: [PATCH 162/230] update unit tests to use changeEvent object --- .../__tests__/functions-mongodb-crud.tests.ts | 208 ++++++++---------- 1 file changed, 93 insertions(+), 115 deletions(-) diff --git a/tests/integration/__tests__/functions-mongodb-crud.tests.ts b/tests/integration/__tests__/functions-mongodb-crud.tests.ts index c9154d9..5bb1c3a 100644 --- a/tests/integration/__tests__/functions-mongodb-crud.tests.ts +++ b/tests/integration/__tests__/functions-mongodb-crud.tests.ts @@ -8,6 +8,7 @@ describe("Test MongoDB CRUD operations in Functions", () => { test("Test inserting and deleting a document with Functions", async () => { class Sale { + _id: ObjectId = new ObjectId(); saleDate?: Date; items?: StoreItem[]; storeLocation?: string; @@ -31,8 +32,36 @@ describe("Test MongoDB CRUD operations in Functions", () => { ){} }; + let ids: ObjectId[] = []; +// CHANGE EVENT // + const changeEvent = { + _id: {_data: new ObjectId("599af247bb69cd89961c986d") }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + userName: 'alice123', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: true, + items: null, + + } + }; + let StoreItems: StoreItem[] = [ { category: "supplies", @@ -55,32 +84,21 @@ describe("Test MongoDB CRUD operations in Functions", () => { const user = await app.logIn(anonCredentials); expect(user).toBeTruthy; - // *********** // - // InsertOne // +// *********** // +// InsertOne // /* returns: { "insertedId": { "$oid": "664515f357125435e7b3e9b6" } }*/ - const customer = new Customer(42,"mary.shelly@example.com",4); - - const insertOneArgs = new Sale(); - insertOneArgs.saleDate = new Date(), - insertOneArgs.items = StoreItems, - insertOneArgs.storeLocation = "Scranton", - insertOneArgs.customer = customer, - insertOneArgs.couponUsed = false, - insertOneArgs.purchaseMethod = "Trinkets"; - let resultId: ObjectId = new ObjectId(); try { const insertResult = (await user.functions.crud_InsertOne( - insertOneArgs + changeEvent )) as InsertOneResult; - if (insertResult.insertedId instanceof ObjectId) { resultId = insertResult.insertedId; } @@ -89,8 +107,10 @@ describe("Test MongoDB CRUD operations in Functions", () => { fail(error.message); } } + ids.push(resultId); expect(ids[0]).toBe(resultId); + expect(ids.length).toBe(1); // *********** // // InsertMany // @@ -104,41 +124,30 @@ describe("Test MongoDB CRUD operations in Functions", () => { } ] }*/ - const insertManyArgs = [{ - saleDate: new Date(), - StoreItems: StoreItems, - storeLocation: "Hoboken", - customer: customer, - couponUsed: false, - purchaseMethod: "Carrier Pigeon", - }, { - saleDate: new Date(), - StoreItems: StoreItems, - storeLocation: "Armpit, NJ", - customer: customer, - couponUsed: false, - purchaseMethod: "Carrier Pigeon" - } -] + class foo{"insertedIds":string[];} - let insertedIds: foo = new foo(); + //let allIds: string[] = new Array(); + try { - const insertManyResult = (await user.functions.crud_InsertMany( - insertManyArgs - )) as foo; + const insertManyResult = await user.functions.crud_InsertMany( + changeEvent + ) as foo; + + //expect(insertManyResult.insertedIds[0]).toContain("sds") + ids.push(new ObjectId(insertManyResult.insertedIds[0])); - insertedIds = insertManyResult; + const insertManyResult2 = (await user.functions.crud_InsertMany( + changeEvent + )) as foo; + ids.push(new ObjectId(insertManyResult2.insertedIds[0])); + } catch (error) { if (error instanceof Error) { fail(error.message); } } - insertedIds.insertedIds.forEach(id => { - ids.push(new ObjectId(id)); - }); - expect(ids).not.toBeNull; expect(ids.length).toBe(3); @@ -154,7 +163,7 @@ describe("Test MongoDB CRUD operations in Functions", () => { try { projectResult = (await user.functions.crud_Project( - ids[0].toString(), projectionFilter)) as Sale; + changeEvent)) as Sale; } catch (error) { if (error instanceof Error) { @@ -168,35 +177,6 @@ describe("Test MongoDB CRUD operations in Functions", () => { expect(projectResult.items?.length).toBe(2); expect(projectResult.saleDate).toBeNull;*/ - const changeEvent = { - _id: {_data: ids[0].toString() }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - userName: 'alice123', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - userName: 'alice123', - name: 'Alice' - } - }; - - // *********** // // REPLACE // /* returns @@ -219,7 +199,7 @@ describe("Test MongoDB CRUD operations in Functions", () => { } expect(replaceResult.couponUsed).toBe(false); - expect(replaceResult.storeLocation).toBe("East Appleton"); + expect(replaceResult.storeLocation).toBe("Orangeville"); // *********** // @@ -232,6 +212,8 @@ describe("Test MongoDB CRUD operations in Functions", () => { "couponUsed": true }*/ + changeEvent._id._data = ids[0]; + let updateResult: Sale = new Sale(); try { @@ -243,62 +225,56 @@ describe("Test MongoDB CRUD operations in Functions", () => { } } + expect(updateResult).not.toBeNull();//("saDfweasdFAs") // *********** // // FindOne // - let updatedDocumentResult: Sale = new Sale(); - try { - updatedDocumentResult = await user.functions.crud_FindOne( - changeEvent) as Sale; - } catch (error) { - if (error instanceof Error) { - fail(error.message); - } - } - expect(updatedDocumentResult.couponUsed).toBe(true) - expect(updatedDocumentResult.storeLocation).toBe("West Appleton"); + changeEvent._id._data = updateResult._id; + let foundResult: Sale = new Sale(); + try { + foundResult = await user.functions.crud_FindOne( + changeEvent) as Sale; + } catch (error) { + if (error instanceof Error) { + fail(error.message); + } + } + + expect(foundResult.storeLocation).toBe("West Appleton"); // *********** // // UPDATEMANY // - /* returns - "_id": { - "$oid": "6644e8613e720767b85fee9f" - }, - "storeLocation": "East Appleton", - "couponUsed": true - }*/ - let count; - - const updateManyFindFilter = { - "purchaseMethod": "Carrier Pigeon" - }; - - const updateManyResultFilter = { - "storeLocation": "Langley", - purchaseMethod: "Carrier Pig" - }; +/* returns +{"matchedCount":{"$numberInt":"0"}, + "modifiedCount":{"$numberInt":"0"}, + "upsertedId":{"$oid":"6679d49446b20ed3fae5541c"}} +*/ + let count = 0; + let updateManyResult: Sale[] = new Array(); try { - const updateOneResult = (await user.functions.crud_UpdateMany( - updateManyFindFilter, updateManyResultFilter)) as UpdateResult; - count = updateOneResult.modifiedCount; + const result = await user.functions.crud_UpdateMany( + changeEvent) as Sale; + updateManyResult.push(result); + count = updateManyResult.length; } catch (error) { if (error instanceof Error) { fail(error.message); } } - expect(count).toBe(1); // *********** // // Find (Many) // + + changeEvent.fullDocument.storeLocation = "Langley" let findResults: Sale[] = []; try { - findResults = (await user.functions.crud_Find( - {purchaseMethod: "Carrier Pig"})) as Sale[]; + findResults = await user.functions.crud_Find( + changeEvent) as Sale[]; } catch (error) { if (error instanceof Error) { fail(error.message); @@ -306,14 +282,13 @@ describe("Test MongoDB CRUD operations in Functions", () => { } expect(findResults).not.toBeNull; - //expect(findResults.length).toBe(2); - expect(findResults[0].purchaseMethod).toBe("Carrier Pig"); + expect(findResults[0].purchaseMethod).toBe("credit"); expect(findResults[0].storeLocation).toBe("Langley"); // *********** // // DeleteOne // const deleteResult = await user.functions.crud_DeleteOne( - {} + changeEvent ) as DeleteResult; expect(deleteResult).toBe(1); @@ -322,12 +297,15 @@ describe("Test MongoDB CRUD operations in Functions", () => { let deleteManyCount: number; deleteManyCount = 0; - deleteManyCount = await user.functions.crud_DeleteMany({}) as number; + deleteManyCount = await user.functions.crud_DeleteMany(changeEvent) as number; //commented out because if any test fails, this doesn't run //TODO: investigate tear-down style test so this always works //expect(deleteManyCount).toBe(2); + + + }, 6000); }) @@ -350,14 +328,14 @@ order of tests: /* UPDATED WITH CHANGE EVENT - InsertOne - InsertMany +✓ InsertOne +✓ InsertMany ✓ FindOne - Project +✓ Project ✓ Replace ✓ UpdateOne - UpdateMany - Find - DeleteOne - DeleteMany +✓ UpdateMany +✓ Find +✓ DeleteOne +✓ DeleteMany */ \ No newline at end of file From 83fcab04f8898f3efb7b3e0973d9ced58b04f447 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 21:20:21 +0000 Subject: [PATCH 163/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index a9ac721..6249509 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -9e15663f210cd6271d4b9f7ed5f8b71d93499aa5 +9ac01f8e29244e8f848e5db4d207fe22a36abca0 From 9f1e4a561386b0750066e83a993af09df4cb5066 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Mon, 24 Jun 2024 23:15:41 +0000 Subject: [PATCH 164/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..532481d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,48 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..aeb1e2a --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 5a0f1a9324e191710ccfe550c61004b74397cf94 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Mon, 24 Jun 2024 23:15:43 +0000 Subject: [PATCH 165/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 39015608a2eba24420ea430836a7d2fab2927c52 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Mon, 24 Jun 2024 23:15:45 +0000 Subject: [PATCH 166/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 5c274055c2836d14a5de630349ad3fbd993e98eb Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 23:15:52 +0000 Subject: [PATCH 167/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 12 files changed, 526 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 532481d..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,48 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index aeb1e2a..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 82b4c85fb2778bf3648b5b54e3ea4934fbfb3799 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 23:15:53 +0000 Subject: [PATCH 168/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 6249509..226ec4a 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -9ac01f8e29244e8f848e5db4d207fe22a36abca0 +5c274055c2836d14a5de630349ad3fbd993e98eb From 8bb60c55f85153c2d1c0a0d38ffb2a4dc0108030 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 23:15:55 +0000 Subject: [PATCH 169/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 226ec4a..0868c51 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -5c274055c2836d14a5de630349ad3fbd993e98eb +82b4c85fb2778bf3648b5b54e3ea4934fbfb3799 From 55ba79fac60f98f96ed67655c7d7fb85bcf06d2b Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 24 Jun 2024 23:15:58 +0000 Subject: [PATCH 170/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 0868c51..89256a5 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -82b4c85fb2778bf3648b5b54e3ea4934fbfb3799 +8bb60c55f85153c2d1c0a0d38ffb2a4dc0108030 From 5b01db3c063d55adf69760e95dcba7c36d6f9138 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 15:39:09 +0000 Subject: [PATCH 171/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..532481d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,48 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..aeb1e2a --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 1d2c2f6351095501fdedf6311c57e66a83548b66 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 15:39:11 +0000 Subject: [PATCH 172/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 662180ff3465192851c06182fa90a5b9ad87fba2 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 15:39:12 +0000 Subject: [PATCH 173/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 33a32dba5b90386ca4c0b63bc13c315660b3e099 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:39:21 +0000 Subject: [PATCH 174/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 89256a5..9452696 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -8bb60c55f85153c2d1c0a0d38ffb2a4dc0108030 +c4e07dbb3eaf32323d0d9b840165996d0609bc8f From 520a159d3335ae5fdda41a319e39d720bbb44aa2 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:39:23 +0000 Subject: [PATCH 175/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 12 files changed, 526 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 532481d..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,48 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index aeb1e2a..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From dfc75e4154e219362c6fe17343e31170e8b95e9c Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:39:24 +0000 Subject: [PATCH 176/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 9452696..c106688 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -c4e07dbb3eaf32323d0d9b840165996d0609bc8f +520a159d3335ae5fdda41a319e39d720bbb44aa2 From f6889da9bebb49faacd9388c77d25aba761a4b93 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 08:47:45 -0700 Subject: [PATCH 177/230] update expression manifest --- snippets/triggers/match/manifest.json | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/snippets/triggers/match/manifest.json b/snippets/triggers/match/manifest.json index 959e0c8..7da8677 100644 --- a/snippets/triggers/match/manifest.json +++ b/snippets/triggers/match/manifest.json @@ -4,10 +4,28 @@ "viewType": "triggerMatch", "snippets": [ { - "id": "ed4b3598-6800-413f-9158-d9b1b2a2a081", - "title": "Match Expression for Updates", - "snippet": "/update.json", - "description": "" + "id": "ed4b3598-6800-413f-9158-d9b1b2a2a081", + "title": "Match Expression for Updates", + "snippet": "/update.json", + "description": "This trigger will only execute if the `storeLocation` array has changed to \"East Langley\" and the \"storeItems\" field has been removed." + }, + { + "id": "ed4b3598-6800-413f-9158-d9b1b2a2a082", + "title": "Match Expression for Deletes", + "snippet": "/delete.json", + "description": "This trigger will only execute if the document (before deletion) has a userName of \"Alice Smith\"" + }, + { + "id": "ed4b3598-6800-413f-9158-d9b1b2a2a083", + "title": "Match Expression for Deletes", + "snippet": "/insert.json", + "description": "This trigger will only execute if the document has a userName of \"Alice Smith\" and a department of \"engineering\"" + }, + { + "id": "ed4b3598-6800-413f-9158-d9b1b2a2a084", + "title": "Match Expression for Replace", + "snippet": "/replace.json", + "description": "This trigger will only execute if the name field was \"Alice Smith\" before the Replace, and \"Alex Smith\" after the Replace." } ] } \ No newline at end of file From e7fde184bc9d97cc980b04bc400d48662c6d857f Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:48:14 +0000 Subject: [PATCH 178/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index c106688..5b39fe9 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -520a159d3335ae5fdda41a319e39d720bbb44aa2 +f6889da9bebb49faacd9388c77d25aba761a4b93 From 23e9491bf5f810d85d7c3ab8a048494e8eeb3165 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 15:55:03 +0000 Subject: [PATCH 179/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..532481d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,48 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..aeb1e2a --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From b198a9a7ab2a716231300c22001c44e132c95b48 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 15:55:04 +0000 Subject: [PATCH 180/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From ecb7bdd699cd18a34cbb330257feec585acb8c4a Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 15:55:06 +0000 Subject: [PATCH 181/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From a9652ea745e662f8914867b9e8dfc70d0d6b2d3b Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:55:16 +0000 Subject: [PATCH 182/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 5b39fe9..6c2bf64 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -f6889da9bebb49faacd9388c77d25aba761a4b93 +d4eb522493609efdc56ceec86fae3cdc6645bcaf From c1d05fdbb87f7dad5119a25f894b289618b92333 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:55:17 +0000 Subject: [PATCH 183/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 12 files changed, 526 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 532481d..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,48 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index aeb1e2a..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 6fc36cc23f5e6aa7067de9980818af95406857f7 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:55:20 +0000 Subject: [PATCH 184/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 6c2bf64..832dfb2 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -d4eb522493609efdc56ceec86fae3cdc6645bcaf +c1d05fdbb87f7dad5119a25f894b289618b92333 From cadacd8cee7658d127025200b2503ae388c1beda Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 15:56:11 +0000 Subject: [PATCH 185/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..532481d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,48 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..aeb1e2a --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 393a42db420885f9ba61f6418375a08cdf146816 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 15:56:14 +0000 Subject: [PATCH 186/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 79a8450673341affe572a9af26c79e23c4edb9cc Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 15:56:17 +0000 Subject: [PATCH 187/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 612c2c60ffdccfcead8b1b9f02059aca875c066f Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:56:23 +0000 Subject: [PATCH 188/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 832dfb2..2794a42 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -c1d05fdbb87f7dad5119a25f894b289618b92333 +2fa361b66948259a493b097af5248fc5c8fc1a25 From ec333fc2c11535d6ab6fb08f1b0bc8e18b6e8d85 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:56:25 +0000 Subject: [PATCH 189/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 12 files changed, 526 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 532481d..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,48 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index aeb1e2a..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From 92f41c31bb6a26d0167299c8c315e5d239cc5b8e Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:56:27 +0000 Subject: [PATCH 190/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 2794a42..d479431 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -2fa361b66948259a493b097af5248fc5c8fc1a25 +ec333fc2c11535d6ab6fb08f1b0bc8e18b6e8d85 From 2f014f73b0f467f86def24198e7e9c2f62250013 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:56:29 +0000 Subject: [PATCH 191/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index d479431..124604d 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -ec333fc2c11535d6ab6fb08f1b0bc8e18b6e8d85 +92f41c31bb6a26d0167299c8c315e5d239cc5b8e From 2aa5ee70776926b2aab34a85c36906a1d6a811c2 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Tue, 25 Jun 2024 15:59:07 +0000 Subject: [PATCH 192/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..532481d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,48 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..f171239 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test thia example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..aeb1e2a --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 41132ea573be8f50b67db17c3ba4e189191c5577 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Tue, 25 Jun 2024 15:59:08 +0000 Subject: [PATCH 193/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 9cb48779021af45a68fc4204aacf8afe9e56ca23 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Tue, 25 Jun 2024 15:59:09 +0000 Subject: [PATCH 194/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 9a1d6e138b3a38891a02106a945e914a5794d1cc Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:59:18 +0000 Subject: [PATCH 195/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 12 files changed, 526 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 532481d..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,48 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index f171239..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test thia example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index aeb1e2a..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From d09c8fd13152f8e301b5dd7c5342e58d1c3d8050 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:59:19 +0000 Subject: [PATCH 196/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 124604d..3c4d72c 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -92f41c31bb6a26d0167299c8c315e5d239cc5b8e +9a1d6e138b3a38891a02106a945e914a5794d1cc From 3cbd0f48989564bf3596f8405f438911bc7c4c3c Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:59:20 +0000 Subject: [PATCH 197/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 3c4d72c..f7c6851 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -9a1d6e138b3a38891a02106a945e914a5794d1cc +d09c8fd13152f8e301b5dd7c5342e58d1c3d8050 From 4e23e63bb052ae68632f51b1f7dd060e87e94ca7 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 15:59:22 +0000 Subject: [PATCH 198/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index f7c6851..ab487f3 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -d09c8fd13152f8e301b5dd7c5342e58d1c3d8050 +3cbd0f48989564bf3596f8405f438911bc7c4c3c From b74217e6fc492afdddad4e32c73eb829d3165e87 Mon Sep 17 00:00:00 2001 From: "mongodb-atlas-app-services[bot]" Date: Tue, 25 Jun 2024 16:01:55 +0000 Subject: [PATCH 199/230] Commit performed using Copy Push Files action --- snippets/triggers/match/delete.json | 3 +++ snippets/triggers/match/insert.json | 4 ++++ snippets/triggers/match/replace.json | 4 ++++ snippets/triggers/match/update.json | 7 +++---- snippets/triggers/project/delete.json | 11 +++++++++++ snippets/triggers/project/insert.json | 14 ++++++++++++++ snippets/triggers/project/replace.json | 11 +++++++++++ snippets/triggers/project/update.json | 11 +++++++---- 8 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 snippets/triggers/match/delete.json create mode 100644 snippets/triggers/match/insert.json create mode 100644 snippets/triggers/match/replace.json create mode 100644 snippets/triggers/project/delete.json create mode 100644 snippets/triggers/project/insert.json create mode 100644 snippets/triggers/project/replace.json diff --git a/snippets/triggers/match/delete.json b/snippets/triggers/match/delete.json new file mode 100644 index 0000000..8426729 --- /dev/null +++ b/snippets/triggers/match/delete.json @@ -0,0 +1,3 @@ +{ + "fullDocumentBeforeChange.userName": "Alice Smith" +} diff --git a/snippets/triggers/match/insert.json b/snippets/triggers/match/insert.json new file mode 100644 index 0000000..b1fbfc1 --- /dev/null +++ b/snippets/triggers/match/insert.json @@ -0,0 +1,4 @@ +{ + "department": "engineering", + "documentKey.userName": "alice123" +} diff --git a/snippets/triggers/match/replace.json b/snippets/triggers/match/replace.json new file mode 100644 index 0000000..671279d --- /dev/null +++ b/snippets/triggers/match/replace.json @@ -0,0 +1,4 @@ +{ + "fullDocument.name": "Alex Smith", + "fullDocumentBeforeChange.name": "Alice Smith" +} diff --git a/snippets/triggers/match/update.json b/snippets/triggers/match/update.json index fe100b1..0accd54 100644 --- a/snippets/triggers/match/update.json +++ b/snippets/triggers/match/update.json @@ -1,5 +1,4 @@ { - "updateDescription.updatedFields": { - "status": "blocked" - } -} \ No newline at end of file + "updateDescription.removedFields.0.0": "storeItems", + "updateDescription.updateFields.storeLocation.0.0": "East Langley" +} diff --git a/snippets/triggers/project/delete.json b/snippets/triggers/project/delete.json new file mode 100644 index 0000000..d22414b --- /dev/null +++ b/snippets/triggers/project/delete.json @@ -0,0 +1,11 @@ +{ + "documentKey._id": { + "$numberInt": "1" + }, + "operationType": { + "$numberInt": "1" + }, + "wallTime": { + "$numberInt": "1" + } +} diff --git a/snippets/triggers/project/insert.json b/snippets/triggers/project/insert.json new file mode 100644 index 0000000..1ead1c1 --- /dev/null +++ b/snippets/triggers/project/insert.json @@ -0,0 +1,14 @@ +{ + "baseSalary": { + "$numberInt": "0" + }, + "department": { + "$numberInt": "1" + }, + "documentKey.userName": { + "$numberInt": "1" + }, + "operationType": { + "$numberInt": "1" + } +} diff --git a/snippets/triggers/project/replace.json b/snippets/triggers/project/replace.json new file mode 100644 index 0000000..7bea317 --- /dev/null +++ b/snippets/triggers/project/replace.json @@ -0,0 +1,11 @@ +{ + "fullDocument.name": { + "$numberInt": "1" + }, + "fullDocumentBeforeChange.name": { + "$numberInt": "1" + }, + "operationType": { + "$numberInt": "1" + } +} diff --git a/snippets/triggers/project/update.json b/snippets/triggers/project/update.json index fe100b1..0536a6d 100644 --- a/snippets/triggers/project/update.json +++ b/snippets/triggers/project/update.json @@ -1,5 +1,8 @@ { - "updateDescription.updatedFields": { - "status": "blocked" - } -} \ No newline at end of file + "operationType": { + "$numberInt": "1" + }, + "updateDescription.updateFields.storeLocation": { + "$numberInt": "1" + } +} From cd057e55e05a47fe868d428d54852628d42271b9 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 16:02:09 +0000 Subject: [PATCH 200/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index ab487f3..11e5afb 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -3cbd0f48989564bf3596f8405f438911bc7c4c3c +d6040166cfa1ee60715d65b0eca6e727ace16b49 From e2388f73b1f6635f983d2dcc434357c6e94eb876 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 09:12:32 -0700 Subject: [PATCH 201/230] update project manifest --- snippets/triggers/project/manifest.json | 28 ++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/snippets/triggers/project/manifest.json b/snippets/triggers/project/manifest.json index b750ee8..785feb3 100644 --- a/snippets/triggers/project/manifest.json +++ b/snippets/triggers/project/manifest.json @@ -1,13 +1,31 @@ { "category": "ProjectTriggerExpressions", - "categoryId": "72e7780e-4382-4dc1-8f23-e7b9dbcf1f80", + "categoryId": "ee1e471e-72c7-4dc9-b80a-9f745836a254", "viewType": "triggerProject", "snippets": [ { - "id": "72e7780e-4382-4dc1-8f23-e7b9dbcf1f81", - "title": "Match Expression for Updates", - "snippet": "/update.json", - "description": "" + "id": "7dd66555-8efb-4a76-8920-64c0874e0214", + "title": "Project Expression for Updates", + "snippet": "/update.json", + "description": "This trigger will return the \"operationType\" and \"updateDescription.updateFields.storeLocation\" field values." + }, + { + "id": "7c9b14f4-30ec-4865-b153-8bd52c6566ad", + "title": "Project Expression for Deletes", + "snippet": "/delete.json", + "description": "This trigger will return the \"documentKey._id\", \"operationType\", and \"wallTime\" field values." + }, + { + "id": "e040947b-08a4-4a8f-9f82-1bccd7826892", + "title": "Project Expression for Deletes", + "snippet": "/insert.json", + "description": "This trigger will return the \"baseSalary\", \"department\", \"operationType\", and \"documentKey.userName\" field values." + }, + { + "id": "90768f43-3d5a-4746-8ccc-f709cda09eae", + "title": "Project Expression for Replace", + "snippet": "/replace.json", + "description": "This trigger will return the \"operationType\", \"fullDocument.name\", and \"fullDocumentBeforeChange.name\" field values." } ] } \ No newline at end of file From 1f25a6ce9b1eb54c92db2b0a8f93973961cb5ef0 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 16:12:47 +0000 Subject: [PATCH 202/230] update commit hash --- latestCommit.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latestCommit.md b/latestCommit.md index 11e5afb..840963b 100644 --- a/latestCommit.md +++ b/latestCommit.md @@ -1 +1 @@ -d6040166cfa1ee60715d65b0eca6e727ace16b49 +e2388f73b1f6635f983d2dcc434357c6e94eb876 From 7edf6832fdd21b0033f6cb4372b04385680cf5b6 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 13:53:51 -0700 Subject: [PATCH 203/230] update action to add git commit hash to manifest rather than extra file --- .github/workflows/Update-Commit-Hash.yml | 14 ++++++-- manifest.json | 41 ++++++++++++------------ 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/.github/workflows/Update-Commit-Hash.yml b/.github/workflows/Update-Commit-Hash.yml index 46d8fbd..da0d02c 100644 --- a/.github/workflows/Update-Commit-Hash.yml +++ b/.github/workflows/Update-Commit-Hash.yml @@ -9,13 +9,23 @@ jobs: permissions: write-all runs-on: ubuntu-latest steps: + - uses: actions/checkout@v2 + - name: 'Setup jq' + uses: dcarbone/install-jq-action@v2 + with: + version: '${{ inputs.version }}' + force: '${{ inputs.force }}' + - id: validate_manifest + run: | + version=$(git log -1 --format='%H') + jq --arg v "${version}" '.version = $v' manifest.json > tempManifest.json + mv tempManifest.json manifest.json - uses: actions/checkout@v3 - name: Update file with merge commit hash run: | git pull origin ${{ github.ref }} - git log -1 --format='%H' > latestCommit.md git config --global user.email "caleb.thompson@mongodb.com" git config --global user.name "ActionBot" - git add latestCommit.md + git add manifest.json git commit -m 'update commit hash' git push origin ${{ github.ref }} \ No newline at end of file diff --git a/manifest.json b/manifest.json index da98953..5c10982 100644 --- a/manifest.json +++ b/manifest.json @@ -1,22 +1,23 @@ { - "snippetCategories": [ - { - "metadata": "/snippets/functions/third-party/manifest.json" - }, - { - "metadata": "/snippets/functions/mongodb-crud/manifest.json" - }, - { - "metadata": "/snippets/functions/api-functions/manifest.json" - }, - { - "metadata": "/snippets/functions/function-context/manifest.json" - }, - { - "metadata": "/snippets/triggers/match/manifest.json" - }, - { - "metadata": "/snippets/triggers/project/manifest.json" - } - ] + "snippetCategories": [ + { + "metadata": "/snippets/functions/third-party/manifest.json" + }, + { + "metadata": "/snippets/functions/mongodb-crud/manifest.json" + }, + { + "metadata": "/snippets/functions/api-functions/manifest.json" + }, + { + "metadata": "/snippets/functions/function-context/manifest.json" + }, + { + "metadata": "/snippets/triggers/match/manifest.json" + }, + { + "metadata": "/snippets/triggers/project/manifest.json" + } + ], + "version": "e2388f73b1f6635f983d2dcc434357c6e94eb876" } From cf927469f675abb59d3901572ee7d76577ac2759 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 13:56:33 -0700 Subject: [PATCH 204/230] add debugging --- .github/workflows/Update-Commit-Hash.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/Update-Commit-Hash.yml b/.github/workflows/Update-Commit-Hash.yml index da0d02c..fa73489 100644 --- a/.github/workflows/Update-Commit-Hash.yml +++ b/.github/workflows/Update-Commit-Hash.yml @@ -18,8 +18,11 @@ jobs: - id: validate_manifest run: | version=$(git log -1 --format='%H') + jq '.version' manifest.json jq --arg v "${version}" '.version = $v' manifest.json > tempManifest.json mv tempManifest.json manifest.json + jq '.version' manifest.json + git diff manifest.json - uses: actions/checkout@v3 - name: Update file with merge commit hash run: | From 132fde19b60e3202ac5894222c2fbfaddaefc91a Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 14:00:53 -0700 Subject: [PATCH 205/230] combine steps --- .github/workflows/Update-Commit-Hash.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/Update-Commit-Hash.yml b/.github/workflows/Update-Commit-Hash.yml index fa73489..dcd1473 100644 --- a/.github/workflows/Update-Commit-Hash.yml +++ b/.github/workflows/Update-Commit-Hash.yml @@ -9,7 +9,7 @@ jobs: permissions: write-all runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: 'Setup jq' uses: dcarbone/install-jq-action@v2 with: @@ -22,10 +22,6 @@ jobs: jq --arg v "${version}" '.version = $v' manifest.json > tempManifest.json mv tempManifest.json manifest.json jq '.version' manifest.json - git diff manifest.json - - uses: actions/checkout@v3 - - name: Update file with merge commit hash - run: | git pull origin ${{ github.ref }} git config --global user.email "caleb.thompson@mongodb.com" git config --global user.name "ActionBot" From 7bc432b1a43192a918d8686d93df4f700225514f Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 21:01:09 +0000 Subject: [PATCH 206/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 5c10982..8697817 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "e2388f73b1f6635f983d2dcc434357c6e94eb876" + "version": "132fde19b60e3202ac5894222c2fbfaddaefc91a" } From 85b9e371e7f449ce71543768fffa8e6d5e09f518 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 25 Jun 2024 14:02:01 -0700 Subject: [PATCH 207/230] remove old file --- latestCommit.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 latestCommit.md diff --git a/latestCommit.md b/latestCommit.md deleted file mode 100644 index 840963b..0000000 --- a/latestCommit.md +++ /dev/null @@ -1 +0,0 @@ -e2388f73b1f6635f983d2dcc434357c6e94eb876 From 0f9d8e44e7d00d290ea719c989eea475c0cf3710 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 25 Jun 2024 21:02:19 +0000 Subject: [PATCH 208/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 8697817..6f614b3 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "132fde19b60e3202ac5894222c2fbfaddaefc91a" + "version": "85b9e371e7f449ce71543768fffa8e6d5e09f518" } From f459ac1d6b69d0b6604fbcc00927d801c8fdb418 Mon Sep 17 00:00:00 2001 From: jwongmongodb <116834447+jwongmongodb@users.noreply.github.com> Date: Mon, 8 Jul 2024 10:08:49 -0400 Subject: [PATCH 209/230] BAAS-30361: add amazon third party snippets (#47) --- manifest.json | 2 +- snippets/functions/third-party/awsKinesis.js | 26 +++++++++++++ .../functions/third-party/awsS3GetObject.js | 26 +++++++++++++ .../functions/third-party/awsS3PutObject.js | 27 +++++++++++++ snippets/functions/third-party/awsSES.js | 38 +++++++++++++++++++ snippets/functions/third-party/manifest.json | 24 ++++++++++++ 6 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 snippets/functions/third-party/awsKinesis.js create mode 100644 snippets/functions/third-party/awsS3GetObject.js create mode 100644 snippets/functions/third-party/awsS3PutObject.js create mode 100644 snippets/functions/third-party/awsSES.js diff --git a/manifest.json b/manifest.json index 6f614b3..45033d2 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "85b9e371e7f449ce71543768fffa8e6d5e09f518" + "version": "b27eb194e608862bb8851f536ea449b6a28ca078" } diff --git a/snippets/functions/third-party/awsKinesis.js b/snippets/functions/third-party/awsKinesis.js new file mode 100644 index 0000000..358b8f6 --- /dev/null +++ b/snippets/functions/third-party/awsKinesis.js @@ -0,0 +1,26 @@ +exports = async function () { + const { + KinesisClient, + DescribeStreamCommand, + } = require("@aws-sdk/client-kinesis"); + const kinesisClient = new KinesisClient({ + credentials: { + accessKeyId: context.values.get("awsAccessKeyID"), + secretAccessKey: context.values.get("awsSecretAccessKey"), + }, + region: "us-east-1", + maxAttempts: 5, + }); + + // see https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/kinesis/ for more commands + const describeStreamCommand = new DescribeStreamCommand({ + StreamName: "myStreamName", + }); + + try { + const data = await kinesisClient.send(describeStreamCommand); + return data.StreamDescription.StreamName; + } catch (error) { + return error; + } +}; diff --git a/snippets/functions/third-party/awsS3GetObject.js b/snippets/functions/third-party/awsS3GetObject.js new file mode 100644 index 0000000..8399253 --- /dev/null +++ b/snippets/functions/third-party/awsS3GetObject.js @@ -0,0 +1,26 @@ +exports = async function () { + const { + S3Client, + GetObjectCommand, + PutObjectCommand, + } = require("@aws-sdk/client-s3"); + const s3Client = new S3Client({ + credentials: { + accessKeyId: context.values.get("awsAccessKeyID"), + secretAccessKey: context.values.get("awsSecretAccessKey"), + }, + region: "us-east-1", + }); + + // see https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/ for more details + const getObjectCommand = new GetObjectCommand({ + Bucket: "myBucketName", + Key: context.values.get("awsBucketKey"), + }); + try { + const data = await s3Client.send(getObjectCommand); + return data; + } catch (error) { + return error; + } +}; diff --git a/snippets/functions/third-party/awsS3PutObject.js b/snippets/functions/third-party/awsS3PutObject.js new file mode 100644 index 0000000..406835b --- /dev/null +++ b/snippets/functions/third-party/awsS3PutObject.js @@ -0,0 +1,27 @@ +exports = async function () { + const { + S3Client, + GetObjectCommand, + PutObjectCommand, + } = require("@aws-sdk/client-s3"); + const s3Client = new S3Client({ + credentials: { + accessKeyId: context.values.get("awsAccessKeyID"), + secretAccessKey: context.values.get("awsSecretAccessKey"), + }, + region: "us-east-1", + }); + + // see https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/ for more details + const putObjectCommand = new PutObjectCommand({ + Bucket: "myBucketName", + Key: context.values.get("awsBucketKey"), + Body: Buffer.from("bucket data"), + }); + try { + const data = await s3Client.send(putObjectCommand); + return data; + } catch (error) { + return error; + } +}; diff --git a/snippets/functions/third-party/awsSES.js b/snippets/functions/third-party/awsSES.js new file mode 100644 index 0000000..fee5f75 --- /dev/null +++ b/snippets/functions/third-party/awsSES.js @@ -0,0 +1,38 @@ +exports = async function () { + const { SESv2Client, SendEmailCommand } = require("@aws-sdk/client-sesv2"); + const sesv2Client = new SESv2Client({ + credentials: { + accessKeyId: context.values.get("awsAccessKeyID"), + secretAccessKey: context.values.get("awsSecretAccessKey"), + }, + region: "us-east-1", + maxAttempts: 5, + }); + + // see https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/sesv2/ for more detail + const sendEmailCommand = new SendEmailCommand({ + FromEmailAddress: "from.email@youremail.com", + Destination: { + ToAddresses: ["to.email@toemail.com"], + }, + Content: { + Simple: { + Subject: { + Data: "HeLLO SES", + }, + Body: { + Text: { + Data: "This is a simple mail", + }, + }, + }, + }, + }); + + try { + const data = await sesv2Client.send(sendEmailCommand); + return data; + } catch (error) { + return error; + } +}; diff --git a/snippets/functions/third-party/manifest.json b/snippets/functions/third-party/manifest.json index ec935ec..0e07a37 100644 --- a/snippets/functions/third-party/manifest.json +++ b/snippets/functions/third-party/manifest.json @@ -20,6 +20,30 @@ "title": "Using node-fetch dependency", "snippet": "/nodeFetch.js", "description": "Making HTTP requests with node-fetch dependency. Atlas App Services does not support v3 of node-fetch, use v2 instead." + }, + { + "id": "fdf44706-adbe-4880-87b5-e9c28f6110af", + "title": "Using AWS SES dependency", + "snippet": "/awsSES.js", + "description": "Sending an email with AWS SES. To authenticate with the AWS client, store your AccessKeyID and SecretAccessKey as values. Note: This is using AWS SDK v3." + }, + { + "id": "fdf44706-adbe-4880-87b5-e9c28f6110ag", + "title": "Using AWS Kinesis dependency", + "snippet": "/awsKinesis.js", + "description": "Retrieving stream details with AWS Kinesis. To authenticate with the AWS client, store your AccessKeyID and SecretAccessKey as values. Note: This is using AWS SDK v3." + }, + { + "id": "fdf44706-adbe-4880-87b5-e9c28f6110aa", + "title": "Retrieving from AWS S3 bucket", + "snippet": "/awsS3GetObject.js", + "description": "Retrieving from AWS S3 bucket with the bucket name and key. To authenticate with the AWS client, store your AccessKeyID and SecretAccessKey as values. Note: This is using AWS SDK v3." + }, + { + "id": "fdf44706-adbe-4880-87b5-e9c28f6110ab", + "title": "Putting object in AWS S3 bucket", + "snippet": "/awsS3PutObject.js", + "description": "Uploads an object to an AWS S3 bucket using the specified bucket name and key. Authentication requires your AWS AccessKeyID, SecretAccessKey and BucketKey, all of which should be stored as values. This operation uses AWS SDK v3." } ] } From b253fd515b9c9233b1a2e3a69c96adcb01c30efe Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 8 Jul 2024 14:09:03 +0000 Subject: [PATCH 210/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 45033d2..097537f 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "b27eb194e608862bb8851f536ea449b6a28ca078" + "version": "f459ac1d6b69d0b6604fbcc00927d801c8fdb418" } From a0709f5948d4f595e013b0001c4c562758c5394f Mon Sep 17 00:00:00 2001 From: jwongmongodb <116834447+jwongmongodb@users.noreply.github.com> Date: Wed, 10 Jul 2024 07:58:03 -0400 Subject: [PATCH 211/230] Update trigger insert title correctly (#48) --- manifest.json | 2 +- snippets/triggers/match/manifest.json | 4 ++-- snippets/triggers/project/manifest.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/manifest.json b/manifest.json index 097537f..2faee6c 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "f459ac1d6b69d0b6604fbcc00927d801c8fdb418" + "version": "ff90d15324e67a2c36d01c3ad87463f68e053c6d" } diff --git a/snippets/triggers/match/manifest.json b/snippets/triggers/match/manifest.json index 7da8677..ee0a057 100644 --- a/snippets/triggers/match/manifest.json +++ b/snippets/triggers/match/manifest.json @@ -17,7 +17,7 @@ }, { "id": "ed4b3598-6800-413f-9158-d9b1b2a2a083", - "title": "Match Expression for Deletes", + "title": "Match Expression for Inserts", "snippet": "/insert.json", "description": "This trigger will only execute if the document has a userName of \"Alice Smith\" and a department of \"engineering\"" }, @@ -28,4 +28,4 @@ "description": "This trigger will only execute if the name field was \"Alice Smith\" before the Replace, and \"Alex Smith\" after the Replace." } ] -} \ No newline at end of file +} diff --git a/snippets/triggers/project/manifest.json b/snippets/triggers/project/manifest.json index 785feb3..4025c78 100644 --- a/snippets/triggers/project/manifest.json +++ b/snippets/triggers/project/manifest.json @@ -17,7 +17,7 @@ }, { "id": "e040947b-08a4-4a8f-9f82-1bccd7826892", - "title": "Project Expression for Deletes", + "title": "Project Expression for Inserts", "snippet": "/insert.json", "description": "This trigger will return the \"baseSalary\", \"department\", \"operationType\", and \"documentKey.userName\" field values." }, @@ -28,4 +28,4 @@ "description": "This trigger will return the \"operationType\", \"fullDocument.name\", and \"fullDocumentBeforeChange.name\" field values." } ] -} \ No newline at end of file +} From bbbe1e02f1e2b4ce065d05c76aa57865c9890c94 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Wed, 10 Jul 2024 11:58:19 +0000 Subject: [PATCH 212/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 2faee6c..ae5b5d7 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "ff90d15324e67a2c36d01c3ad87463f68e053c6d" + "version": "a0709f5948d4f595e013b0001c4c562758c5394f" } From 0d9fc40397acdf4f4b9547029bb7fb492da18f52 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 16 Jul 2024 18:58:28 +0000 Subject: [PATCH 213/230] Commit performed using Copy Push Files action --- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ++++++++++++++++ .../functions/mongodb-crud/crud_DeleteOne.js | 49 ++++++++++++++++ snippets/functions/mongodb-crud/crud_Find.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_FindOne.js | 56 ++++++++++++++++++ .../functions/mongodb-crud/crud_InsertMany.js | 47 +++++++++++++++ .../functions/mongodb-crud/crud_InsertOne.js | 45 +++++++++++++++ .../functions/mongodb-crud/crud_Project.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_Replace.js | 49 ++++++++++++++++ .../functions/mongodb-crud/crud_UpdateMany.js | 57 +++++++++++++++++++ .../functions/mongodb-crud/crud_UpdateOne.js | 54 ++++++++++++++++++ 10 files changed, 503 insertions(+) create mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js create mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Find.js create mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js create mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js create mode 100644 snippets/functions/mongodb-crud/crud_Project.js create mode 100644 snippets/functions/mongodb-crud/crud_Replace.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js create mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js new file mode 100644 index 0000000..532481d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteMany.js @@ -0,0 +1,48 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; + + try { + deleteResult = await collection.deleteMany(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js new file mode 100644 index 0000000..56afd1c --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_DeleteOne.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + console.log(JSON.stringify(changeEvent)); + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + const deleteFilter = { "_id": changeEvent._id._data }; + try { + deleteResult = await collection.deleteOne(deleteFilter); + return deleteResult["deletedCount"]; + } catch(err) { + console.log("Failed to delete item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js new file mode 100644 index 0000000..e46a93d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Find.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); + + try { + findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); + return findResults; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "599af247bb69cd89961c986d" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js new file mode 100644 index 0000000..893012b --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_FindOne.js @@ -0,0 +1,56 @@ +exports = async function(changeEvent){ + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + var serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + var dbName = "sample_supplies"; + var collName = "sales"; + + // Get a collection from the context + var collection = context.services.get(serviceName).db(dbName).collection(collName); + + // To test this example, uncomment the following line: + // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); + + const query = { "_id": changeEvent._id._data }; + + try { + doc = await collection.findOne(query); + return doc; + + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '599af247bb69cd89961c986d' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "599af247bb69cd89961c986d" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + couponUsed: false + } +}); +*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js new file mode 100644 index 0000000..1c66e93 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertMany.js @@ -0,0 +1,47 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertMany([ + {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, + ]); + return result; + } catch (err) { + console.log("Failed to insert items: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: { + "$oid": "62548f79e7f11292792497cc" + } + }, + fullDocument: { + _id: { + "$oid": "599af247bb69cd89961c986d" + }, + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js new file mode 100644 index 0000000..f5df3d8 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_InsertOne.js @@ -0,0 +1,45 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + try { + var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, + "items":changeEvent.fullDocument.items}); + return result; + } catch (err) { + console.log("Failed to insert item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js new file mode 100644 index 0000000..6a20fc7 --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Project.js @@ -0,0 +1,49 @@ +exports = async function(changeEvent){ + var serviceName = "mongodb-atlas"; + var dbName = "sample_supplies"; + var collName = "sales"; + + var collection = context.services.get(serviceName).db(dbName).collection(collName); + const query = { "_id": changeEvent.documentKey._id }; + + const projection = { + _id:0, + storeLocation:1, + items: 1 + } + + try { + doc = await collection.findOne(query, projection); + return doc; + } catch(err) { + console.log("Failed to find item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: '62548f79e7f11292792497cc' + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + items: ["envelopes"] + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js new file mode 100644 index 0000000..227493d --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_Replace.js @@ -0,0 +1,49 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test the above example, insert the following document into your collection: + //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + const replacement = { + storeLocation: "Orangeville", + couponUsed: false, + }; + + const options = { returnNewDocument: true }; + + try { + return await collection.findOneAndReplace(query, replacement, options); + } catch (err) { + console.log("Failed to replace item: ", err.message); + return { error: err.message }; + } +}; + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton' + } +})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js new file mode 100644 index 0000000..73465ab --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateMany.js @@ -0,0 +1,57 @@ +exports = async function (changeEvent) { + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) + + const query = { storeLocation: changeEvent.fullDocument.storeLocation }; + + // Example update filter: + const updateFilter = { + "$set": { + "storeLocation": "Langley", + "purchaseMethod" : "credit" + } + }; + + const options = { "upsert": true }; + + try { + updateResult = await collection.updateMany(query, updateFilter, options); + return updateResult; + + } catch(err) { + console.log("Failed to update item(s): ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "599af247bb69cd89961c986d", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js new file mode 100644 index 0000000..aeb1e2a --- /dev/null +++ b/snippets/functions/mongodb-crud/crud_UpdateOne.js @@ -0,0 +1,54 @@ +exports = async function (changeEvent) { + + console.log(JSON.stringify(changeEvent)); + + var collection = context.services + .get("mongodb-atlas") + .db("sample_supplies") + .collection("sales"); + + // To test this example, uncomment the following line: + // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); + + const query = { _id: changeEvent._id._data }; + + const updateFields = { + storeLocation: "West Appleton", + couponUsed: true, + }; + + try { + await collection.updateOne(query, updateFields); + return await collection.findOne(query); + } catch (err) { + console.log("Failed to update item: ", err.message); + return { error: err.message }; + } +} + +// In the Testing Console tab, paste the code below and click Run: +/* +exports({ + _id: {_data: '62548f79e7f11292792497cc' }, + operationType: 'insert', + clusterTime: { + "$timestamp": { + t: 1649712420, + i:6 + } + }, + ns: { + db: 'engineering', + coll: 'users' + }, + documentKey: { + storeLocation: 'East Appleton', + _id: "62548f79e7f11292792497cc" + }, + fullDocument: { + _id: "62548f79e7f11292792497cc", + storeLocation: 'East Appleton', + couponUsed: false + } +}) +*/ \ No newline at end of file From 5ced8038b9fd1cc8386840442849f27a731602bb Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 16 Jul 2024 18:58:29 +0000 Subject: [PATCH 214/230] Commit performed using Copy Push Files action --- snippets/functions/api-functions/api_callExternalAPI.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 snippets/functions/api-functions/api_callExternalAPI.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js new file mode 100644 index 0000000..19f0d42 --- /dev/null +++ b/snippets/functions/api-functions/api_callExternalAPI.js @@ -0,0 +1,9 @@ +exports = async function(arg){ + const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; + + const response = await context.http.get({ url: url }) + // The response body is a BSON.Binary object, so parse it: + const result = EJSON.parse(response.body.text()) + // console.log(JSON.stringify(result)); + return result; +} \ No newline at end of file From 8b4ebd459ad55803ac02fe8da81a8ac3f6e6fe73 Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 16 Jul 2024 18:58:30 +0000 Subject: [PATCH 215/230] Commit performed using Copy Push Files action --- .../function-context/context_callFunction.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 snippets/functions/function-context/context_callFunction.js diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js new file mode 100644 index 0000000..f22f6d4 --- /dev/null +++ b/snippets/functions/function-context/context_callFunction.js @@ -0,0 +1,14 @@ +exports = async function(number1, number2){ + + // To call other named functions: + var result = context.functions.execute("sum", number1, number2); + + return result; +}; + +// This examples calls a function named "sum" that looks like this: +/* + exports = async function(number1, number2) { + return number1 + number2 + }; +*/ \ No newline at end of file From 51ca752cef4fefe29b66c4e775c4fe87ca58209b Mon Sep 17 00:00:00 2001 From: MongoCaleb Date: Tue, 16 Jul 2024 18:58:34 +0000 Subject: [PATCH 216/230] Commit performed using Copy Push Files action --- snippets/triggers/match/delete.json | 3 +++ snippets/triggers/match/insert.json | 4 ++++ snippets/triggers/match/replace.json | 4 ++++ snippets/triggers/match/update.json | 7 +++---- snippets/triggers/project/delete.json | 11 +++++++++++ snippets/triggers/project/insert.json | 14 ++++++++++++++ snippets/triggers/project/replace.json | 11 +++++++++++ snippets/triggers/project/update.json | 11 +++++++---- 8 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 snippets/triggers/match/delete.json create mode 100644 snippets/triggers/match/insert.json create mode 100644 snippets/triggers/match/replace.json create mode 100644 snippets/triggers/project/delete.json create mode 100644 snippets/triggers/project/insert.json create mode 100644 snippets/triggers/project/replace.json diff --git a/snippets/triggers/match/delete.json b/snippets/triggers/match/delete.json new file mode 100644 index 0000000..8426729 --- /dev/null +++ b/snippets/triggers/match/delete.json @@ -0,0 +1,3 @@ +{ + "fullDocumentBeforeChange.userName": "Alice Smith" +} diff --git a/snippets/triggers/match/insert.json b/snippets/triggers/match/insert.json new file mode 100644 index 0000000..b1fbfc1 --- /dev/null +++ b/snippets/triggers/match/insert.json @@ -0,0 +1,4 @@ +{ + "department": "engineering", + "documentKey.userName": "alice123" +} diff --git a/snippets/triggers/match/replace.json b/snippets/triggers/match/replace.json new file mode 100644 index 0000000..671279d --- /dev/null +++ b/snippets/triggers/match/replace.json @@ -0,0 +1,4 @@ +{ + "fullDocument.name": "Alex Smith", + "fullDocumentBeforeChange.name": "Alice Smith" +} diff --git a/snippets/triggers/match/update.json b/snippets/triggers/match/update.json index fe100b1..0accd54 100644 --- a/snippets/triggers/match/update.json +++ b/snippets/triggers/match/update.json @@ -1,5 +1,4 @@ { - "updateDescription.updatedFields": { - "status": "blocked" - } -} \ No newline at end of file + "updateDescription.removedFields.0.0": "storeItems", + "updateDescription.updateFields.storeLocation.0.0": "East Langley" +} diff --git a/snippets/triggers/project/delete.json b/snippets/triggers/project/delete.json new file mode 100644 index 0000000..d22414b --- /dev/null +++ b/snippets/triggers/project/delete.json @@ -0,0 +1,11 @@ +{ + "documentKey._id": { + "$numberInt": "1" + }, + "operationType": { + "$numberInt": "1" + }, + "wallTime": { + "$numberInt": "1" + } +} diff --git a/snippets/triggers/project/insert.json b/snippets/triggers/project/insert.json new file mode 100644 index 0000000..1ead1c1 --- /dev/null +++ b/snippets/triggers/project/insert.json @@ -0,0 +1,14 @@ +{ + "baseSalary": { + "$numberInt": "0" + }, + "department": { + "$numberInt": "1" + }, + "documentKey.userName": { + "$numberInt": "1" + }, + "operationType": { + "$numberInt": "1" + } +} diff --git a/snippets/triggers/project/replace.json b/snippets/triggers/project/replace.json new file mode 100644 index 0000000..7bea317 --- /dev/null +++ b/snippets/triggers/project/replace.json @@ -0,0 +1,11 @@ +{ + "fullDocument.name": { + "$numberInt": "1" + }, + "fullDocumentBeforeChange.name": { + "$numberInt": "1" + }, + "operationType": { + "$numberInt": "1" + } +} diff --git a/snippets/triggers/project/update.json b/snippets/triggers/project/update.json index fe100b1..0536a6d 100644 --- a/snippets/triggers/project/update.json +++ b/snippets/triggers/project/update.json @@ -1,5 +1,8 @@ { - "updateDescription.updatedFields": { - "status": "blocked" - } -} \ No newline at end of file + "operationType": { + "$numberInt": "1" + }, + "updateDescription.updateFields.storeLocation": { + "$numberInt": "1" + } +} From 25fd847940065be4fed3065b95c3f6102b041895 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 16 Jul 2024 18:58:40 +0000 Subject: [PATCH 217/230] remove function name prefix --- .../api-functions/api_callExternalAPI.js | 9 --- .../function-context/context_callFunction.js | 14 ----- snippets/functions/mongodb-crud/UpdateMany.js | 2 +- .../functions/mongodb-crud/crud_DeleteMany.js | 48 ---------------- .../functions/mongodb-crud/crud_DeleteOne.js | 49 ---------------- snippets/functions/mongodb-crud/crud_Find.js | 49 ---------------- .../functions/mongodb-crud/crud_FindOne.js | 56 ------------------ .../functions/mongodb-crud/crud_InsertMany.js | 47 --------------- .../functions/mongodb-crud/crud_InsertOne.js | 45 --------------- .../functions/mongodb-crud/crud_Project.js | 49 ---------------- .../functions/mongodb-crud/crud_Replace.js | 49 ---------------- .../functions/mongodb-crud/crud_UpdateMany.js | 57 ------------------- .../functions/mongodb-crud/crud_UpdateOne.js | 54 ------------------ 13 files changed, 1 insertion(+), 527 deletions(-) delete mode 100644 snippets/functions/api-functions/api_callExternalAPI.js delete mode 100644 snippets/functions/function-context/context_callFunction.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_DeleteOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Find.js delete mode 100644 snippets/functions/mongodb-crud/crud_FindOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_InsertOne.js delete mode 100644 snippets/functions/mongodb-crud/crud_Project.js delete mode 100644 snippets/functions/mongodb-crud/crud_Replace.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateMany.js delete mode 100644 snippets/functions/mongodb-crud/crud_UpdateOne.js diff --git a/snippets/functions/api-functions/api_callExternalAPI.js b/snippets/functions/api-functions/api_callExternalAPI.js deleted file mode 100644 index 19f0d42..0000000 --- a/snippets/functions/api-functions/api_callExternalAPI.js +++ /dev/null @@ -1,9 +0,0 @@ -exports = async function(arg){ - const url = "https://api.stackexchange.com/2.3/answers?key=U4DMV*8nvpm3EOpvf69Rxw((&site=stackoverflow&page=1&pagesize=10&order=desc&sort=activity&filter=default"; - - const response = await context.http.get({ url: url }) - // The response body is a BSON.Binary object, so parse it: - const result = EJSON.parse(response.body.text()) - // console.log(JSON.stringify(result)); - return result; -} \ No newline at end of file diff --git a/snippets/functions/function-context/context_callFunction.js b/snippets/functions/function-context/context_callFunction.js deleted file mode 100644 index f22f6d4..0000000 --- a/snippets/functions/function-context/context_callFunction.js +++ /dev/null @@ -1,14 +0,0 @@ -exports = async function(number1, number2){ - - // To call other named functions: - var result = context.functions.execute("sum", number1, number2); - - return result; -}; - -// This examples calls a function named "sum" that looks like this: -/* - exports = async function(number1, number2) { - return number1 + number2 - }; -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/UpdateMany.js b/snippets/functions/mongodb-crud/UpdateMany.js index f171239..73465ab 100644 --- a/snippets/functions/mongodb-crud/UpdateMany.js +++ b/snippets/functions/mongodb-crud/UpdateMany.js @@ -4,7 +4,7 @@ exports = async function (changeEvent) { .db("sample_supplies") .collection("sales"); - // To test thia example, uncomment the following line: + // To test this example, uncomment the following line: // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) const query = { storeLocation: changeEvent.fullDocument.storeLocation }; diff --git a/snippets/functions/mongodb-crud/crud_DeleteMany.js b/snippets/functions/mongodb-crud/crud_DeleteMany.js deleted file mode 100644 index 532481d..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteMany.js +++ /dev/null @@ -1,48 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "storeLocation": changeEvent.fullDocument.storeLocation }; - - try { - deleteResult = await collection.deleteMany(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_DeleteOne.js b/snippets/functions/mongodb-crud/crud_DeleteOne.js deleted file mode 100644 index 56afd1c..0000000 --- a/snippets/functions/mongodb-crud/crud_DeleteOne.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - console.log(JSON.stringify(changeEvent)); - - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - const deleteFilter = { "_id": changeEvent._id._data }; - try { - deleteResult = await collection.deleteOne(deleteFilter); - return deleteResult["deletedCount"]; - } catch(err) { - console.log("Failed to delete item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Find.js b/snippets/functions/mongodb-crud/crud_Find.js deleted file mode 100644 index e46a93d..0000000 --- a/snippets/functions/mongodb-crud/crud_Find.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, "couponUsed":true}); - - try { - findResults = await collection.find({storeLocation: changeEvent.fullDocument.storeLocation}); - return findResults; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "599af247bb69cd89961c986d" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_FindOne.js b/snippets/functions/mongodb-crud/crud_FindOne.js deleted file mode 100644 index 893012b..0000000 --- a/snippets/functions/mongodb-crud/crud_FindOne.js +++ /dev/null @@ -1,56 +0,0 @@ -exports = async function(changeEvent){ - // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) - var serviceName = "mongodb-atlas"; - - // Update these to reflect your db/collection - var dbName = "sample_supplies"; - var collName = "sales"; - - // Get a collection from the context - var collection = context.services.get(serviceName).db(dbName).collection(collName); - - // To test this example, uncomment the following line: - // collection.updateOne({_id:"599af247bb69cd89961c986d", "storeLocation":"East Appleton", "couponUsed":false}, {upsert:true}); - - const query = { "_id": changeEvent._id._data }; - - try { - doc = await collection.findOne(query); - return doc; - - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '599af247bb69cd89961c986d' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "599af247bb69cd89961c986d" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - couponUsed: false - } -}); -*/ diff --git a/snippets/functions/mongodb-crud/crud_InsertMany.js b/snippets/functions/mongodb-crud/crud_InsertMany.js deleted file mode 100644 index 1c66e93..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertMany.js +++ /dev/null @@ -1,47 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertMany([ - {"storeLocation":changeEvent.fullDocument.storeLocation, "items":changeEvent.fullDocument.items}, - ]); - return result; - } catch (err) { - console.log("Failed to insert items: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: { - "$oid": "62548f79e7f11292792497cc" - } - }, - fullDocument: { - _id: { - "$oid": "599af247bb69cd89961c986d" - }, - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_InsertOne.js b/snippets/functions/mongodb-crud/crud_InsertOne.js deleted file mode 100644 index f5df3d8..0000000 --- a/snippets/functions/mongodb-crud/crud_InsertOne.js +++ /dev/null @@ -1,45 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - try { - var result = await collection.insertOne({"storeLocation":changeEvent.fullDocument.storeLocation, - "items":changeEvent.fullDocument.items}); - return result; - } catch (err) { - console.log("Failed to insert item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Project.js b/snippets/functions/mongodb-crud/crud_Project.js deleted file mode 100644 index 6a20fc7..0000000 --- a/snippets/functions/mongodb-crud/crud_Project.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function(changeEvent){ - var serviceName = "mongodb-atlas"; - var dbName = "sample_supplies"; - var collName = "sales"; - - var collection = context.services.get(serviceName).db(dbName).collection(collName); - const query = { "_id": changeEvent.documentKey._id }; - - const projection = { - _id:0, - storeLocation:1, - items: 1 - } - - try { - doc = await collection.findOne(query, projection); - return doc; - } catch(err) { - console.log("Failed to find item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: '62548f79e7f11292792497cc' - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - items: ["envelopes"] - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_Replace.js b/snippets/functions/mongodb-crud/crud_Replace.js deleted file mode 100644 index 227493d..0000000 --- a/snippets/functions/mongodb-crud/crud_Replace.js +++ /dev/null @@ -1,49 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test the above example, insert the following document into your collection: - //await collection.insertOne({"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - const replacement = { - storeLocation: "Orangeville", - couponUsed: false, - }; - - const options = { returnNewDocument: true }; - - try { - return await collection.findOneAndReplace(query, replacement, options); - } catch (err) { - console.log("Failed to replace item: ", err.message); - return { error: err.message }; - } -}; - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton' - } -})*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateMany.js b/snippets/functions/mongodb-crud/crud_UpdateMany.js deleted file mode 100644 index 73465ab..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateMany.js +++ /dev/null @@ -1,57 +0,0 @@ -exports = async function (changeEvent) { - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // collection.updateOne({"storeLocation":"East Appleton","couponUsed":false}) - - const query = { storeLocation: changeEvent.fullDocument.storeLocation }; - - // Example update filter: - const updateFilter = { - "$set": { - "storeLocation": "Langley", - "purchaseMethod" : "credit" - } - }; - - const options = { "upsert": true }; - - try { - updateResult = await collection.updateMany(query, updateFilter, options); - return updateResult; - - } catch(err) { - console.log("Failed to update item(s): ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "599af247bb69cd89961c986d", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file diff --git a/snippets/functions/mongodb-crud/crud_UpdateOne.js b/snippets/functions/mongodb-crud/crud_UpdateOne.js deleted file mode 100644 index aeb1e2a..0000000 --- a/snippets/functions/mongodb-crud/crud_UpdateOne.js +++ /dev/null @@ -1,54 +0,0 @@ -exports = async function (changeEvent) { - - console.log(JSON.stringify(changeEvent)); - - var collection = context.services - .get("mongodb-atlas") - .db("sample_supplies") - .collection("sales"); - - // To test this example, uncomment the following line: - // await collection.updateOne({"_id":changeEvent._id._data,"storeLocation":"East Appleton","couponUsed":false}, {upsert:true}); - - const query = { _id: changeEvent._id._data }; - - const updateFields = { - storeLocation: "West Appleton", - couponUsed: true, - }; - - try { - await collection.updateOne(query, updateFields); - return await collection.findOne(query); - } catch (err) { - console.log("Failed to update item: ", err.message); - return { error: err.message }; - } -} - -// In the Testing Console tab, paste the code below and click Run: -/* -exports({ - _id: {_data: '62548f79e7f11292792497cc' }, - operationType: 'insert', - clusterTime: { - "$timestamp": { - t: 1649712420, - i:6 - } - }, - ns: { - db: 'engineering', - coll: 'users' - }, - documentKey: { - storeLocation: 'East Appleton', - _id: "62548f79e7f11292792497cc" - }, - fullDocument: { - _id: "62548f79e7f11292792497cc", - storeLocation: 'East Appleton', - couponUsed: false - } -}) -*/ \ No newline at end of file From b4b7c4daf8b2bddfd5c5c840f5d3c989afcf0c66 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 16 Jul 2024 18:58:45 +0000 Subject: [PATCH 218/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index ae5b5d7..6f4dbf6 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "a0709f5948d4f595e013b0001c4c562758c5394f" + "version": "d2de28d9e0967f028b5e02fd70359c7d69b87ece" } From 7e5bf28650dfc9e8d3981859adeaa8525fdb2034 Mon Sep 17 00:00:00 2001 From: jwongmongodb <116834447+jwongmongodb@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:02:24 -0400 Subject: [PATCH 219/230] BAAS-32668: shorten snippet expression titles based on product feedback (#49) --- manifest.json | 2 +- snippets/triggers/match/manifest.json | 58 ++++++++++++------------- snippets/triggers/project/manifest.json | 58 ++++++++++++------------- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/manifest.json b/manifest.json index 6f4dbf6..198fe34 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "d2de28d9e0967f028b5e02fd70359c7d69b87ece" + "version": "8bb1d7311fce8c4c74f97ae0a717fda4be280865" } diff --git a/snippets/triggers/match/manifest.json b/snippets/triggers/match/manifest.json index ee0a057..9e94f5b 100644 --- a/snippets/triggers/match/manifest.json +++ b/snippets/triggers/match/manifest.json @@ -1,31 +1,31 @@ { - "category": "MatchTriggerExpressions", - "categoryId": "ed4b3598-6800-413f-9158-d9b1b2a2a080", - "viewType": "triggerMatch", - "snippets": [ - { - "id": "ed4b3598-6800-413f-9158-d9b1b2a2a081", - "title": "Match Expression for Updates", - "snippet": "/update.json", - "description": "This trigger will only execute if the `storeLocation` array has changed to \"East Langley\" and the \"storeItems\" field has been removed." - }, - { - "id": "ed4b3598-6800-413f-9158-d9b1b2a2a082", - "title": "Match Expression for Deletes", - "snippet": "/delete.json", - "description": "This trigger will only execute if the document (before deletion) has a userName of \"Alice Smith\"" - }, - { - "id": "ed4b3598-6800-413f-9158-d9b1b2a2a083", - "title": "Match Expression for Inserts", - "snippet": "/insert.json", - "description": "This trigger will only execute if the document has a userName of \"Alice Smith\" and a department of \"engineering\"" - }, - { - "id": "ed4b3598-6800-413f-9158-d9b1b2a2a084", - "title": "Match Expression for Replace", - "snippet": "/replace.json", - "description": "This trigger will only execute if the name field was \"Alice Smith\" before the Replace, and \"Alex Smith\" after the Replace." - } - ] + "category": "MatchTriggerExpressions", + "categoryId": "ed4b3598-6800-413f-9158-d9b1b2a2a080", + "viewType": "triggerMatch", + "snippets": [ + { + "id": "ed4b3598-6800-413f-9158-d9b1b2a2a081", + "title": "Updates", + "snippet": "/update.json", + "description": "This trigger will only execute if the `storeLocation` array has changed to \"East Langley\" and the \"storeItems\" field has been removed." + }, + { + "id": "ed4b3598-6800-413f-9158-d9b1b2a2a082", + "title": "Deletes", + "snippet": "/delete.json", + "description": "This trigger will only execute if the document (before deletion) has a userName of \"Alice Smith\"" + }, + { + "id": "ed4b3598-6800-413f-9158-d9b1b2a2a083", + "title": "Inserts", + "snippet": "/insert.json", + "description": "This trigger will only execute if the document has a userName of \"Alice Smith\" and a department of \"engineering\"" + }, + { + "id": "ed4b3598-6800-413f-9158-d9b1b2a2a084", + "title": "Replace", + "snippet": "/replace.json", + "description": "This trigger will only execute if the name field was \"Alice Smith\" before the Replace, and \"Alex Smith\" after the Replace." + } + ] } diff --git a/snippets/triggers/project/manifest.json b/snippets/triggers/project/manifest.json index 4025c78..6dfd28b 100644 --- a/snippets/triggers/project/manifest.json +++ b/snippets/triggers/project/manifest.json @@ -1,31 +1,31 @@ { - "category": "ProjectTriggerExpressions", - "categoryId": "ee1e471e-72c7-4dc9-b80a-9f745836a254", - "viewType": "triggerProject", - "snippets": [ - { - "id": "7dd66555-8efb-4a76-8920-64c0874e0214", - "title": "Project Expression for Updates", - "snippet": "/update.json", - "description": "This trigger will return the \"operationType\" and \"updateDescription.updateFields.storeLocation\" field values." - }, - { - "id": "7c9b14f4-30ec-4865-b153-8bd52c6566ad", - "title": "Project Expression for Deletes", - "snippet": "/delete.json", - "description": "This trigger will return the \"documentKey._id\", \"operationType\", and \"wallTime\" field values." - }, - { - "id": "e040947b-08a4-4a8f-9f82-1bccd7826892", - "title": "Project Expression for Inserts", - "snippet": "/insert.json", - "description": "This trigger will return the \"baseSalary\", \"department\", \"operationType\", and \"documentKey.userName\" field values." - }, - { - "id": "90768f43-3d5a-4746-8ccc-f709cda09eae", - "title": "Project Expression for Replace", - "snippet": "/replace.json", - "description": "This trigger will return the \"operationType\", \"fullDocument.name\", and \"fullDocumentBeforeChange.name\" field values." - } - ] + "category": "ProjectTriggerExpressions", + "categoryId": "ee1e471e-72c7-4dc9-b80a-9f745836a254", + "viewType": "triggerProject", + "snippets": [ + { + "id": "7dd66555-8efb-4a76-8920-64c0874e0214", + "title": "Updates", + "snippet": "/update.json", + "description": "This trigger will return the \"operationType\" and \"updateDescription.updateFields.storeLocation\" field values." + }, + { + "id": "7c9b14f4-30ec-4865-b153-8bd52c6566ad", + "title": "Deletes", + "snippet": "/delete.json", + "description": "This trigger will return the \"documentKey._id\", \"operationType\", and \"wallTime\" field values." + }, + { + "id": "e040947b-08a4-4a8f-9f82-1bccd7826892", + "title": "Inserts", + "snippet": "/insert.json", + "description": "This trigger will return the \"baseSalary\", \"department\", \"operationType\", and \"documentKey.userName\" field values." + }, + { + "id": "90768f43-3d5a-4746-8ccc-f709cda09eae", + "title": "Replace", + "snippet": "/replace.json", + "description": "This trigger will return the \"operationType\", \"fullDocument.name\", and \"fullDocumentBeforeChange.name\" field values." + } + ] } From 2fa9f6297b510525d1ff971fec5612bb6b41ac3c Mon Sep 17 00:00:00 2001 From: ActionBot Date: Mon, 22 Jul 2024 17:02:36 +0000 Subject: [PATCH 220/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 198fe34..53237de 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "8bb1d7311fce8c4c74f97ae0a717fda4be280865" + "version": "7e5bf28650dfc9e8d3981859adeaa8525fdb2034" } From d04d084298c27e7c755e36c9f61c00ac9e836f56 Mon Sep 17 00:00:00 2001 From: jwongmongodb <116834447+jwongmongodb@users.noreply.github.com> Date: Fri, 26 Jul 2024 09:45:23 -0400 Subject: [PATCH 221/230] BAAS-32668: fix trigger expression titles (#50) --- manifest.json | 2 +- snippets/triggers/match/manifest.json | 6 +++--- snippets/triggers/project/manifest.json | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/manifest.json b/manifest.json index 53237de..8d60f6c 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "7e5bf28650dfc9e8d3981859adeaa8525fdb2034" + "version": "046d33bcdf2f4dee96e07171e3c6a11fc258d419" } diff --git a/snippets/triggers/match/manifest.json b/snippets/triggers/match/manifest.json index 9e94f5b..e18bcc4 100644 --- a/snippets/triggers/match/manifest.json +++ b/snippets/triggers/match/manifest.json @@ -5,19 +5,19 @@ "snippets": [ { "id": "ed4b3598-6800-413f-9158-d9b1b2a2a081", - "title": "Updates", + "title": "Update", "snippet": "/update.json", "description": "This trigger will only execute if the `storeLocation` array has changed to \"East Langley\" and the \"storeItems\" field has been removed." }, { "id": "ed4b3598-6800-413f-9158-d9b1b2a2a082", - "title": "Deletes", + "title": "Delete", "snippet": "/delete.json", "description": "This trigger will only execute if the document (before deletion) has a userName of \"Alice Smith\"" }, { "id": "ed4b3598-6800-413f-9158-d9b1b2a2a083", - "title": "Inserts", + "title": "Insert", "snippet": "/insert.json", "description": "This trigger will only execute if the document has a userName of \"Alice Smith\" and a department of \"engineering\"" }, diff --git a/snippets/triggers/project/manifest.json b/snippets/triggers/project/manifest.json index 6dfd28b..905d08c 100644 --- a/snippets/triggers/project/manifest.json +++ b/snippets/triggers/project/manifest.json @@ -5,19 +5,19 @@ "snippets": [ { "id": "7dd66555-8efb-4a76-8920-64c0874e0214", - "title": "Updates", + "title": "Update", "snippet": "/update.json", "description": "This trigger will return the \"operationType\" and \"updateDescription.updateFields.storeLocation\" field values." }, { "id": "7c9b14f4-30ec-4865-b153-8bd52c6566ad", - "title": "Deletes", + "title": "Delete", "snippet": "/delete.json", "description": "This trigger will return the \"documentKey._id\", \"operationType\", and \"wallTime\" field values." }, { "id": "e040947b-08a4-4a8f-9f82-1bccd7826892", - "title": "Inserts", + "title": "Insert", "snippet": "/insert.json", "description": "This trigger will return the \"baseSalary\", \"department\", \"operationType\", and \"documentKey.userName\" field values." }, From 34d437cb6fb38aacebc6febd4f4310326291abf2 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Fri, 26 Jul 2024 13:45:34 +0000 Subject: [PATCH 222/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 8d60f6c..f38bb05 100644 --- a/manifest.json +++ b/manifest.json @@ -19,5 +19,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "046d33bcdf2f4dee96e07171e3c6a11fc258d419" + "version": "d04d084298c27e7c755e36c9f61c00ac9e836f56" } From fbed7f6073483f23a99d43ee11e21af1b6b036b1 Mon Sep 17 00:00:00 2001 From: jwongmongodb <116834447+jwongmongodb@users.noreply.github.com> Date: Tue, 3 Sep 2024 17:06:46 -0400 Subject: [PATCH 223/230] BAAS-34011: add boilerplate snippets (#51) --- manifest.json | 5 ++- .../functions/boilerplate/databaseTrigger.js | 40 ++++++++++++++++++ .../boilerplate/eventbridgeErrorFunction.js | 18 ++++++++ .../functions/boilerplate/generalFunction.js | 42 +++++++++++++++++++ snippets/functions/boilerplate/manifest.json | 31 ++++++++++++++ .../functions/boilerplate/scheduledTrigger.js | 21 ++++++++++ 6 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 snippets/functions/boilerplate/databaseTrigger.js create mode 100644 snippets/functions/boilerplate/eventbridgeErrorFunction.js create mode 100644 snippets/functions/boilerplate/generalFunction.js create mode 100644 snippets/functions/boilerplate/manifest.json create mode 100644 snippets/functions/boilerplate/scheduledTrigger.js diff --git a/manifest.json b/manifest.json index f38bb05..46d7e33 100644 --- a/manifest.json +++ b/manifest.json @@ -3,6 +3,9 @@ { "metadata": "/snippets/functions/third-party/manifest.json" }, + { + "metadata": "/snippets/functions/boilerplate/manifest.json" + }, { "metadata": "/snippets/functions/mongodb-crud/manifest.json" }, @@ -19,5 +22,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "d04d084298c27e7c755e36c9f61c00ac9e836f56" + "version": "86e6c130f442b25a8cabba7e140acde80e58f085" } diff --git a/snippets/functions/boilerplate/databaseTrigger.js b/snippets/functions/boilerplate/databaseTrigger.js new file mode 100644 index 0000000..508921d --- /dev/null +++ b/snippets/functions/boilerplate/databaseTrigger.js @@ -0,0 +1,40 @@ +exports = async function (changeEvent) { + // A Database Trigger will always call a function with a changeEvent. + // Documentation on ChangeEvents: https://www.mongodb.com/docs/manual/reference/change-events + + // This sample function will listen for events and replicate them to a collection in a different Database + + // Access the _id of the changed document: + const docId = changeEvent.documentKey._id; + + // Get the MongoDB service you want to use (see "Linked Data Sources" tab) + const serviceName = "mongodb-atlas"; + const databaseName = "other_db_name"; + const collection = context.services + .get(serviceName) + .db(databaseName) + .collection(changeEvent.ns.coll); + + // Get the "FullDocument" present in the Insert/Replace/Update ChangeEvents + try { + // If this is a "delete" event, delete the document in the other collection + if (changeEvent.operationType === "delete") { + await collection.deleteOne({ _id: docId }); + } + + // If this is an "insert" event, insert the document into the other collection + else if (changeEvent.operationType === "insert") { + await collection.insertOne(changeEvent.fullDocument); + } + + // If this is an "update" or "replace" event, then replace the document in the other collection + else if ( + changeEvent.operationType === "update" || + changeEvent.operationType === "replace" + ) { + await collection.replaceOne({ _id: docId }, changeEvent.fullDocument); + } + } catch (err) { + console.log("error performing mongodb write: ", err.message); + } +}; diff --git a/snippets/functions/boilerplate/eventbridgeErrorFunction.js b/snippets/functions/boilerplate/eventbridgeErrorFunction.js new file mode 100644 index 0000000..fb8c4f5 --- /dev/null +++ b/snippets/functions/boilerplate/eventbridgeErrorFunction.js @@ -0,0 +1,18 @@ +exports = async function (error, changeEvent) { + // This sample function will log additional details if the error is not + // a DOCUMENT_TOO_LARGE error + if (error.code === "DOCUMENT_TOO_LARGE") { + console.log("Document too large error"); + + // Comment out the line below in order to skip this event and not suspend the Trigger + throw new Error(`Encountered error: ${error.code}`); + } + + console.log("Error sending event to EventBridge"); + console.log(`DB: ${changeEvent.ns.db}`); + console.log(`Collection: ${changeEvent.ns.coll}`); + console.log(`Operation type: ${changeEvent.operationType}`); + + // Throw an error in your function to suspend the trigger and stop processing additional events + throw new Error(`Encountered error: ${error.message}`); +}; diff --git a/snippets/functions/boilerplate/generalFunction.js b/snippets/functions/boilerplate/generalFunction.js new file mode 100644 index 0000000..3c6055f --- /dev/null +++ b/snippets/functions/boilerplate/generalFunction.js @@ -0,0 +1,42 @@ +exports = async function (arg) { + // This default function will get a value and find a document in MongoDB + // To see plenty more examples of what you can do with functions see: + // https://www.mongodb.com/docs/atlas/app-services/functions/ + + // Find the name of the MongoDB service you want to use (see "Linked Data Sources" tab) + const serviceName = "mongodb-atlas"; + + // Update these to reflect your db/collection + const dbName = "db_name"; + const collName = "coll_name"; + + // Get a collection from the context + const collection = context.services + .get(serviceName) + .db(dbName) + .collection(collName); + + let findResult; + try { + // Get a value from the context (see "Values" tab) + // Update this to reflect your value's name. + const valueName = "value_name"; + const value = context.values.get(valueName); + + // Execute a FindOne in MongoDB + findResult = await collection.findOne({ + owner_id: context.user.id, + fieldName: value, + argField: arg, + }); + } catch (err) { + console.log("Error occurred while executing findOne:", err.message); + + return { error: err.message }; + } + + // To call other named functions: + // const result = context.functions.execute("function_name", arg1, arg2); + + return { result: findResult }; +}; diff --git a/snippets/functions/boilerplate/manifest.json b/snippets/functions/boilerplate/manifest.json new file mode 100644 index 0000000..63348fa --- /dev/null +++ b/snippets/functions/boilerplate/manifest.json @@ -0,0 +1,31 @@ +{ + "category": "Boilerplate Template by Function Type", + "categoryId": "4756072f-b3c7-4469-b038-cdf6b346789c", + "viewType": "functionSnippet", + "snippets": [ + { + "id": "7c84ed29-b8b2-466c-af3d-c240889d3112", + "title": "Database Trigger", + "snippet": "/databaseTrigger.js", + "description": "Example shows a template for a DB trigger function, which always accepts a changeEvent as an argument." + }, + { + "id": "ba6113d7-5e52-48e4-8ab4-03df30c0d61a", + "title": "Scheduled Trigger", + "snippet": "/scheduledTrigger.js", + "description": "Shows an example of a Scheduled Trigger function, which will always call a function without arguments." + }, + { + "id": "1dca4a58-c150-4a8e-b602-9edf5c338f3d", + "title": "General Function", + "snippet": "/generalFunction.js", + "description": "Example of a default function that will get a value and find a document in MongoDB, the parameters passed in the header differ from other templates." + }, + { + "id": "b43b9abb-dde7-4389-880e-38ef995d501a", + "title": "Eventbridge Custom Error Function", + "snippet": "/eventbridgeErrorFunction.js", + "description": "Example of a custom error function, which takes in the error and changeEvent as arguments." + } + ] +} diff --git a/snippets/functions/boilerplate/scheduledTrigger.js b/snippets/functions/boilerplate/scheduledTrigger.js new file mode 100644 index 0000000..df4d635 --- /dev/null +++ b/snippets/functions/boilerplate/scheduledTrigger.js @@ -0,0 +1,21 @@ +exports = async function () { + // A Scheduled Trigger will always call a function without arguments. + // Documentation on Triggers: https://www.mongodb.com/docs/atlas/app-services/triggers/ + + // Functions run by Triggers are run as System users and have full access to Services, Functions, and MongoDB Data. + + // Get the MongoDB service you want to use (see "Linked Data Sources" tab) + const serviceName = "mongodb-atlas"; + const databaseName = "db_name"; + const collectionName = "coll_name"; + const collection = context.services + .get(serviceName) + .db(databaseName) + .collection(collectionName); + + try { + const doc = await collection.findOne({ name: "mongodb" }); + } catch (err) { + console.log("error performing mongodb findOne: ", err.message); + } +}; From 46f7deba5ed31bf337cf51a3cab5294e7bec30af Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 3 Sep 2024 21:07:06 +0000 Subject: [PATCH 224/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 46d7e33..5432c45 100644 --- a/manifest.json +++ b/manifest.json @@ -22,5 +22,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "86e6c130f442b25a8cabba7e140acde80e58f085" + "version": "fbed7f6073483f23a99d43ee11e21af1b6b036b1" } From 7bd6521bcefa9ffb7dcfb7ad653044950d6027d1 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Tue, 10 Sep 2024 13:23:56 +0000 Subject: [PATCH 225/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index f73d904..af3aef1 100644 --- a/manifest.json +++ b/manifest.json @@ -22,5 +22,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "446a3bc4656af9df843c707e1b71f88cf81e9a53" + "version": "e95fc03701d3d37b57b2a236cecacf3f7c1317fd" } From c7d2aa07264ae292c45e7770a83fa56f1c23f695 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Wed, 11 Sep 2024 14:30:30 +0000 Subject: [PATCH 226/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index af3aef1..9af2de1 100644 --- a/manifest.json +++ b/manifest.json @@ -22,5 +22,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "e95fc03701d3d37b57b2a236cecacf3f7c1317fd" + "version": "7bd6521bcefa9ffb7dcfb7ad653044950d6027d1" } From 75eff3cd4d37c2058d69d057f30fa8f464ef98d8 Mon Sep 17 00:00:00 2001 From: ActionBot Date: Wed, 11 Sep 2024 14:44:47 +0000 Subject: [PATCH 227/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 9af2de1..cb6f78e 100644 --- a/manifest.json +++ b/manifest.json @@ -22,5 +22,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "7bd6521bcefa9ffb7dcfb7ad653044950d6027d1" + "version": "c7d2aa07264ae292c45e7770a83fa56f1c23f695" } From 18b41b880fe317f441126c43012150c0bff70cf5 Mon Sep 17 00:00:00 2001 From: jwongmongodb <116834447+jwongmongodb@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:47:27 -0400 Subject: [PATCH 228/230] Dev update (#1) --- .github/workflows/zip-and-upload-to-s3-production.yml | 6 +++--- manifest.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/zip-and-upload-to-s3-production.yml b/.github/workflows/zip-and-upload-to-s3-production.yml index dbc0d00..e70da42 100644 --- a/.github/workflows/zip-and-upload-to-s3-production.yml +++ b/.github/workflows/zip-and-upload-to-s3-production.yml @@ -1,9 +1,9 @@ -name: Zip and Upload to S3 for Development +name: Zip and Upload to S3 for Production on: push: branches: - - production + - main jobs: deploy-after-testing: @@ -21,4 +21,4 @@ jobs: aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws_bucket: ${{ secrets.AWS_BUCKET }} source_dir: ./zip - destination_dir: "v1/production" \ No newline at end of file + destination_dir: "v1/production" diff --git a/manifest.json b/manifest.json index cb6f78e..2de8862 100644 --- a/manifest.json +++ b/manifest.json @@ -22,5 +22,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "c7d2aa07264ae292c45e7770a83fa56f1c23f695" + "version": "bddff2bfa773cd34a5cbf951442c95fe8e7b714e" } From 4a3530b26957c255ea47a77842c0a46a5a08330a Mon Sep 17 00:00:00 2001 From: ActionBot Date: Wed, 11 Sep 2024 14:47:37 +0000 Subject: [PATCH 229/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 2de8862..606a1e9 100644 --- a/manifest.json +++ b/manifest.json @@ -22,5 +22,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "bddff2bfa773cd34a5cbf951442c95fe8e7b714e" + "version": "18b41b880fe317f441126c43012150c0bff70cf5" } From 9e75a55533175842e9eb73e0de0f15d0c5389aef Mon Sep 17 00:00:00 2001 From: ActionBot Date: Wed, 11 Sep 2024 14:49:05 +0000 Subject: [PATCH 230/230] update commit hash --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index bfcf6ce..c4032f5 100644 --- a/manifest.json +++ b/manifest.json @@ -22,5 +22,5 @@ "metadata": "/snippets/triggers/project/manifest.json" } ], - "version": "a1c17cc564ffff9fe3413fdba419df03c8e34778" + "version": "7395fc1e8214723dc941ed9e718b4ea36d303e1c" }