1

Note: this is almost exactly the same as NodeJS driver warnings: the options [xxxx] is not supported, and similar to Why am I getting this deprecated warning?! MongoDB, except in my case I actually am closing the connection in-between uses

What I'm trying to do is use the node.js driver to create a db class that can handle everything related to storing and getting data so that everything is a lot easier when I get to creating my backend. The way I'm doing this is by using methods that do various things. Currently I have a listDatabases method, a listCollections method, and a setDatabase method. The listDatabases method connects then returns the admin.listDatabases(), and then disconnects. The listCollections method connects, returns the db.collections() method and the disconnects. The setDatabase method connects, sets a variable to the database object and returns the listCollections() method for the new database, and then disconnects.

I'm currently testing all of this by getting the databases, logging that, then setting the database and logging it.

The errors I'm getting are:

(node:43816) [MONGODB DRIVER] Warning: the options [servers] is not supported
(node:43816) [MONGODB DRIVER] Warning: the options [caseTranslate] is not supported 
(node:43816) [MONGODB DRIVER] Warning: the options [dbName] is not supported

and I'm getting these errors the second time I try to do something (in this case setting the database). They don't seem to do anything but I looked it up and it said that they could have unknown consequences, which kind of scares me.

One thing I found online is that this could be happening because my program is connecting again while it's already connected. I've confirmed that this is not the case both using (too many) console.log's, and making it so that it checks if it's already connected with mongoClient.isConnected() before trying to connect again.

My full code (I'm using typescript):

import { Collection, Cursor, Db, MongoClient } from 'mongodb';
import util from 'util';

interface result<type> {
    result: string;
    code: string;
    data?: type;
}

interface dbListOptions {
    getFullData?: boolean;
}
interface dbListData {
    databases: { name: string; sizeOnDisk: bigint; empty: boolean }[];
    totalSize: bigint;
    ok: bigint;
}

interface colListOptions {
    getFullData?: boolean;
}

class db {
    mongoUrl: string = 'mongodb://127.0.0.1:27017/?retryWrites=true&w=majority';

    mongoOptions: object = { useNewUrlParser: true, useUnifiedTopology: true };

    mongoClient: MongoClient = new MongoClient(
        this.mongoUrl,
        this.mongoOptions
    );

    cursorDatabase?: Db;

    cursorCollection?: Collection;

    cursor?: Cursor;

    constructor(database?: string, collection?: string) {
        if (database) {
            const client = this.mongoClient;
            client.connect().then(() => {
                this.cursorDatabase = client.db(database);
                if (collection) {
                    this.cursorDatabase.collection(
                        collection,
                        { strict: true },
                        (err, col) => {
                            this.cursorCollection = col;
                            client.close();
                        }
                    );
                }
            });
        }
    }

    async connect() {
        if (!this.mongoClient.isConnected()) {
            console.log(this.mongoClient.isConnected());
            await this.mongoClient.connect();
            console.log('Connected');
        }
    }

    async close() {
        if (this.mongoClient.isConnected()) {
            console.log(this.mongoClient.isConnected());
            await this.mongoClient.close();
            console.log('Disconnected');
        }
    }

    async listDatabases(options: dbListOptions = {}) {
        const client = this.mongoClient;
        let result: result<any>;
        try {
            console.log('Pre-Pre-Connect');
            await this.connect();
            console.log('Post-Connect');
            const data: dbListData = await client
                .db('admin')
                .admin()
                .listDatabases();
            result = {
                result: 'SUCCESS',
                code: 'GOT DATABASES',
                data,
            };
        } finally {
            await this.close();
        }
        result ||= { result: 'ERROR', code: 'UNKNOWN ERROR' };
        if (!options.getFullData && result.data) {
            if (!Array.isArray(result.data)) {
                result.data = Array.from(
                    result.data.databases,
                    (obj: { name: string }) => obj.name
                );
            }
        }
        return result;
    }

    get databases() {
        return this.listDatabases();
    }

    async setDatabase(dbName: string, options: colListOptions = {}) {
        const client = this.mongoClient;
        let result: result<Collection[]>;
        try {
            console.log('Pre-Pre-Connect');
            await this.connect();
            console.log('Post-Connect');
            this.cursorDatabase = client.db(dbName);
            const colListResult: result<Collection[]> =
                await this.listCollections();
            const data: Collection[] | undefined = await colListResult.data;
            result = data
                ? {
                        result: 'SUCCESS',
                        code: 'SET DATABASE AND GOT COLLECTIONS',
                        data,
                  }
                : {
                        result: 'ERROR',
                        code: 'COULD NOT GET COLLECTIONS',
                  };
        } finally {
            await this.close();
        }
        result ||= { result: 'ERROR', code: 'UNKNOWN ERROR' };
        if (result.data?.length === 0) {
            result = { result: 'WARN', code: 'DATABASE EMPTY', data: [] };
        }
        return result;
    }

    async listCollections(options: colListOptions = {}, dbName?: string) {
        const client = this.mongoClient;
        let result: result<any>;
        try {
            const database: Db | undefined = dbName
                ? client.db(dbName)
                : this.cursorDatabase;
            if (database) {
                console.log('Pre-Pre-Connect');
                await this.connect();
                console.log('Post-Connect');
                const data: Collection[] = await database.collections();
                result = {
                    result: 'SUCCESS',
                    code: 'GOT COLLECTIONS',
                    data,
                };
            } else {
                result = { result: 'ERROR', code: 'NO DATABASE PROVIDED' };
            }
        } finally {
            await this.close();
        }
        result ||= { result: 'ERROR', code: 'UNKNOWN ERROR' };
        if (!options.getFullData && result.data) {
            if (!Array.isArray(result.data)) {
                result.data = Array.from(
                    result.data.databases,
                    (obj: { name: string }) => obj.name
                );
            }
        }
        return result;
    }
}

(async function () {
    const testdb = await new db();
    const databases: result<dbListData> = await testdb.listDatabases();
    console.log(util.inspect(databases, true, 3));
    const collections: result<Collection[]> = await testdb.setDatabase(
        'storage'
    );
    console.log(util.inspect(collections, true, 2));
})();

EDIT: I solved the problem, it turns out that you have to make a new mongoClient every time you use connect / disconnect, otherwise there is data held between connections that causes problems.

Great_Guy96
  • 11
  • 1
  • 2

0 Answers0