diff --git a/src/command/close.rs b/src/command/close.rs new file mode 100644 index 00000000..d8fd6a8d --- /dev/null +++ b/src/command/close.rs @@ -0,0 +1,13 @@ +use crate::*; + +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct CloseResult { + success: bool, +} + +pub fn close(command: Command) -> util::JsonResult { + let client_id: &usize = &command.args.client_id.unwrap(); + CLIENTS.lock().map_err(|e| e.to_string())?.remove(client_id); + Ok(CloseResult { success: true }) +} diff --git a/src/command/mod.rs b/src/command/mod.rs index c77d7a14..67debf6b 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -1,4 +1,5 @@ mod aggregation; +mod close; mod connect; mod count; mod delete; @@ -11,6 +12,7 @@ mod list_database_names; mod update; pub use aggregation::aggregate; +pub use close::close; pub use connect::{connect_with_options, connect_with_uri}; pub use count::count; pub use delete::delete; diff --git a/src/lib.rs b/src/lib.rs index a6b28237..fb043058 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,6 +35,7 @@ lazy_static! { pub enum CommandType { ConnectWithOptions, ConnectWithUri, + Close, ListDatabases, Find, ListCollectionNames, @@ -114,6 +115,7 @@ fn op_command(_interface: &mut dyn Interface, zero_copy: &mut [ZeroCopyBuf]) -> match args2.command_type { CommandType::ConnectWithOptions => util::sync_op(command::connect_with_options, command), CommandType::ConnectWithUri => util::sync_op(command::connect_with_uri, command), + CommandType::Close => util::sync_op(command::close, command), CommandType::ListDatabases => util::async_op(command::list_database_names, command), CommandType::ListCollectionNames => util::async_op(command::list_collection_names, command), CommandType::Find => util::async_op(command::find, command), diff --git a/test.ts b/test.ts index 380d179d..30a4c827 100644 --- a/test.ts +++ b/test.ts @@ -1,13 +1,13 @@ import { cargoBuild } from "./build.ts"; -import { init } from "./ts/util.ts"; -import { MongoClient } from "./ts/client.ts"; import { assert, assertEquals, - exists, assertThrowsAsync, + exists, } from "./test.deps.ts"; +import { MongoClient } from "./ts/client.ts"; import { ObjectId } from "./ts/types.ts"; +import { init } from "./ts/util.ts"; interface IUser { username: string; password: string; @@ -17,9 +17,13 @@ interface IUser { const { test } = Deno; const dateNow = Date.now(); +let testClient: MongoClient | undefined; + function getClient(): MongoClient { + if (testClient) return testClient; const client = new MongoClient(); client.connectWithUri("mongodb://localhost:27017"); + testClient = client; return client; } @@ -73,13 +77,17 @@ test("testInsertOne", async () => { test("testUpsertOne", async () => { const db = getClient().database("test"); const users = db.collection("mongo_test_users"); - const { upsertedId } = await users.updateOne({ - _id: ObjectId("aaaaaaaaaaaaaaaaaaaaaaaa"), - }, { - username: "user1", - password: "pass1", - date: new Date(dateNow), - }, { upsert: true }); + const { upsertedId } = await users.updateOne( + { + _id: ObjectId("aaaaaaaaaaaaaaaaaaaaaaaa"), + }, + { + username: "user1", + password: "pass1", + date: new Date(dateNow), + }, + { upsert: true } + ); assert(upsertedId); assertEquals(Object.keys(upsertedId), ["$oid"]); @@ -111,7 +119,7 @@ test("testInsertOneTwice", async () => { username: "user1", }) as any, undefined, - "E11000", + "E11000" ); }); @@ -162,11 +170,14 @@ test("testFindOr", async () => { const db = getClient().database("test"); const users = db.collection("mongo_test_users"); const user1 = await users.find({ - $or: [{ - password: "pass1", - }, { - password: "pass2", - }], + $or: [ + { + password: "pass1", + }, + { + password: "pass2", + }, + ], }); assert(user1 instanceof Array); @@ -178,7 +189,7 @@ test("testFind", async () => { const users = db.collection("mongo_test_users"); const findUsers = await users.find( { username: "many" }, - { skip: 1, limit: 1 }, + { skip: 1, limit: 1 } ); assert(findUsers instanceof Array); assertEquals(findUsers.length, 1); @@ -209,7 +220,7 @@ test("testUpdateMany", async () => { const users = db.collection("mongo_test_users"); const result = await users.updateMany( { username: "many" }, - { $set: { username: "MANY" } }, + { $set: { username: "MANY" } } ); assertEquals(result, { matchedCount: 2, modifiedCount: 2, upsertedId: null }); }); @@ -238,6 +249,12 @@ test("testDistinct", async () => { // console.log(result); // }); +test("testClose", async () => { + const result = getClient().close(); + assertEquals(result, { success: true }); + testClient = undefined; +}); + if (await exists(".deno_plugins")) { await Deno.remove(".deno_plugins", { recursive: true }); } diff --git a/ts/client.ts b/ts/client.ts index 56c21242..263efbab 100644 --- a/ts/client.ts +++ b/ts/client.ts @@ -1,6 +1,6 @@ import { Database } from "./database.ts"; import { CommandType } from "./types.ts"; -import { decode, dispatch, dispatchAsync, encode } from "./util.ts"; +import { dispatch, dispatchAsync, encode } from "./util.ts"; export interface ClientOptions { /** @@ -100,7 +100,7 @@ export class MongoClient { connectWithUri(uri: string) { const data = dispatch( { command_type: CommandType.ConnectWithUri }, - encode(uri), + encode(uri) ) as ConnectResult; this._clientId = data.clientId; } @@ -108,7 +108,7 @@ export class MongoClient { connectWithOptions(options: ClientOptions) { const data = dispatch( { command_type: CommandType.ConnectWithOptions }, - encode(JSON.stringify(options)), + encode(JSON.stringify(options)) ) as ConnectResult; this._clientId = data.clientId; } @@ -120,6 +120,15 @@ export class MongoClient { })) as string[]; } + close() { + return dispatch({ + command_type: CommandType.Close, + client_id: this._clientId, + }) as { + success: boolean; + }; + } + database(name: string): Database { return new Database(this, name); } diff --git a/ts/types.ts b/ts/types.ts index 2afde110..9134d789 100644 --- a/ts/types.ts +++ b/ts/types.ts @@ -1,6 +1,7 @@ export enum CommandType { ConnectWithUri = "ConnectWithUri", ConnectWithOptions = "ConnectWithOptions", + Close = "Close", ListDatabases = "ListDatabases", ListCollectionNames = "ListCollectionNames", Find = "Find",