routes/mongodb/mongodb-routes.js

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const express_1 = __importDefault(require("express"));
const database_1 = require("../../config/database");
/**
 * Description placeholder
 *
 * @type {*}
 */
const router = express_1.default.Router();
/**
 * Description placeholder
 *
 * @param {AuthenticatedRequest} req
 * @param {express.Response} res
 * @param {express.NextFunction} next
 */
const authenticateToken = (req, res, next) => {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];
    if (!token) {
        res.status(401).json({ message: 'No token provided' });
        return;
    }
    jsonwebtoken_1.default.verify(token, process.env.JWT_SECRET, (err, user) => {
        if (err)
            return res.status(403).json({ message: 'Invalid token' });
        req.user = user; // Save user data for further use
        next();
    });
};
// POST Endpoint for GIS Schema
router.post('/gisSchema', authenticateToken, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    const { dbName, county, data } = req.body;
    if (!dbName) {
        return res.status(400).json({ message: 'Database name is required' });
    }
    if (!county || !data) {
        return res.status(400).json({ message: 'Collection name and data are required' });
    }
    try {
        // Check if a document exists in the collection
        const db = yield (0, database_1.connectToDatabase)(dbName);
        const existingDoc = yield db.collection(county).findOne({}, { projection: { _id: 1 } });
        if (!existingDoc) {
            // If no document exists, insert a new one
            const result = yield db.collection(county).insertOne(data);
            return res.status(201).json({ message: 'Data inserted successfully', result });
        }
        // If a document exists, update it
        const result = yield db.collection(county).updateOne({ _id: existingDoc._id }, // Use the `_id` of the first document
        { $set: data } // Update the document with the provided data
        );
        res.status(200).json({
            message: 'Data updated successfully',
            matchedCount: result.matchedCount,
            modifiedCount: result.modifiedCount,
        });
    }
    catch (err) {
        console.error('Error updating data:', err);
        res.status(500).json({ message: 'Failed to update data', error: err.message });
    }
    finally {
        yield (0, database_1.closeClient)();
    }
}));
router.get('/gisSchema', authenticateToken, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const client = yield (0, database_1.connectToDatabase)(); // Connect to the MongoDB client
        const adminDb = client.admin(); // Access the admin database
        // Retrieve the list of databases
        const databases = yield adminDb.listDatabases();
        // Filter out `admin` and `local` databases
        const filteredDatabases = databases.databases
            .map((db) => db.name)
            .filter((dbName) => dbName !== 'admin'
            && dbName !== 'local'
            && dbName !== 'available_layers'
            && dbName !== 'auth-users');
        const layersDb = yield (0, database_1.connectToDatabase)('available_layers');
        const layers = yield layersDb.collection('layers').findOne({}, { projection: { _id: 0 } });
        console.log(layers);
        // Retrieve collections and their data for each database
        const collectionsDataByDatabase = {};
        for (const dbName of filteredDatabases) {
            const db = yield (0, database_1.connectToDatabase)(dbName); // Access each database
            const collections = yield db.listCollections().toArray(); // Retrieve collections
            collectionsDataByDatabase[dbName] = {}; // Initialize the database entry
            for (const collection of collections) {
                const collectionName = collection.name;
                const collectionData = yield db.collection(collectionName).findOne({}); // Fetch the first document
                // Initialize `availableLayers` with predefined layers
                const availableLayers = {
                    FLOOD: {
                        TYPE: "FLOOD",
                        URL: "/flood-data/",
                        LAYER_NAME: layers ? layers["flood"].toUpperCase() : "0"
                    },
                    NGS: {
                        TYPE: "NGS",
                        URL: "/ngs-data/",
                        LAYER_NAME: layers ? layers["ngs"].toUpperCase() : "0"
                    }
                };
                if (collectionData === null || collectionData === void 0 ? void 0 : collectionData.baseUrls) {
                    // Process `baseUrls` to dynamically add layers
                    for (const [layerKey] of Object.entries(collectionData.baseUrls)) {
                        availableLayers[layerKey.toUpperCase()] = {
                            TYPE: layerKey.toUpperCase(),
                            URL: `/data-${layerKey.toLowerCase()}/`,
                            LAYER_NAME: layers ? layers[layerKey].toUpperCase() : "0"
                        };
                    }
                }
                // Add `availableLayers` to the collection data
                if (collectionData) {
                    collectionData.availableLayers = availableLayers;
                }
                // Store the modified collection data
                collectionsDataByDatabase[dbName][collectionName] = collectionData;
            }
        }
        res.status(200).json({
            message: 'Databases, collections, and their data retrieved successfully',
            databases: collectionsDataByDatabase
        });
    }
    catch (err) {
        console.error('Error retrieving data:', err);
        res.status(500).json({ message: 'Failed to retrieve data', error: err.message });
    }
    finally {
        yield (0, database_1.closeClient)();
    }
}));
// POST Endpoint to Rename Database
router.post('/renameDatabase', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    const { oldDbName, newDbName } = req.body;
    if (!oldDbName || !newDbName) {
        return res.status(400).json({ message: 'Both old and new database names are required' });
    }
    try {
        const oldDb = yield (0, database_1.connectToDatabase)(oldDbName);
        const newDb = yield (0, database_1.connectToDatabase)(newDbName);
        // List all collections in the old database
        const collections = yield oldDb.listCollections().toArray();
        for (const collection of collections) {
            const collectionName = collection.name;
            // Fetch all documents from the current collection
            const data = yield oldDb.collection(collectionName).find().toArray();
            if (data.length > 0) {
                // Insert documents into the corresponding collection in the new database
                yield newDb.collection(collectionName).insertMany(data);
            }
            else {
                // Create an empty collection if no data exists
                yield newDb.createCollection(collectionName);
            }
        }
        // Drop the old database after successfully copying
        yield oldDb.dropDatabase();
        res.status(200).json({ message: `Database renamed from ${oldDbName} to ${newDbName}` });
    }
    catch (err) {
        console.error('Error renaming database:', err);
        res.status(500).json({ message: 'Failed to rename database', error: err.message });
    }
    finally {
        yield (0, database_1.closeClient)();
    }
}));
router.delete('/deleteDatabase', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    const { dbName } = req.body;
    if (!dbName) {
        return res.status(400).json({ message: 'Database name is required' });
    }
    try {
        const db = yield (0, database_1.connectToDatabase)(dbName);
        // Drop the database
        yield db.dropDatabase();
        res.status(200).json({ message: `Database '${dbName}' deleted successfully` });
    }
    catch (err) {
        console.error('Error deleting database:', err);
        res.status(500).json({ message: 'Failed to delete database', error: err.message });
    }
    finally {
        yield (0, database_1.closeClient)();
    }
}));
exports.default = router;
{
    /*
    curl -X POST http://localhost:5000/api/renameDatabase \
    -H "Content-Type: application/json" \
    -d '{
      "oldDbName": "test_database",
      "newDbName": "test_new_databases"
    }'
    
    curl -X DELETE http://localhost:5000/api/deleteDatabase \
    -H "Content-Type: application/json" \
    -d '{
      "dbName": "test_new_database"
    }'
     */
}