UNPKG

minervajs-mochuelo

Version:

Modulo para la gestión del Modelo de Datos, muy util para desarrollos basados en 'Base de Datos Primero'

506 lines (476 loc) 17.7 kB
/** * @module ModelManager * @description Clase que gestiona la carga, recuperación, adición, actualización y eliminación y manipulación de atributos de columnas en modelos desde un archivo JSON. */ const fs = require('fs'); const path = require('path'); const Model = require('./model'); /** * @class ModelManager * @description Clase que gestiona los modelos. */ class ModelManager { /** * @constructor * @param {string} [filePath='models.json'] - Ruta del archivo JSON que contiene las definiciones de los modelos. */ constructor(filePath = 'models.json') { this.filePath = path.resolve(__dirname, '../../../' + filePath); // Correccion por rutas relativas '../../../' this.models = this.loadModels(); } /** * @function loadModels * @description Carga los modelos desde el archivo JSON. * @returns {object} - Un objeto que contiene los modelos cargados, indexados por su nombre. */ loadModels() { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const models = {}; jsonData.tables.forEach((table) => { models[table.name] = new Model(table); }); return models; } catch (error) { console.error('Error loading models:', error); return {}; } } /** * @function getModel * @description Obtiene un modelo por su nombre. * @param {string} name - Nombre del modelo a recuperar. * @returns {Model|undefined} - El modelo encontrado o undefined si no se encuentra. */ getModel(name) { return this.models[name]; } /** * @function getModelList * @description Devuelve un array con la lista de nombres de todos los modelos cargados. * @returns {string[]} - Un array de nombres de modelos. */ getModelList() { return Object.keys(this.models); } /** * @function addModel * @description Agrega un nuevo modelo al archivo JSON y a la instancia de ModelManager. * @param {object} modelDefinition - Definición del modelo a agregar. * @returns {boolean} - Verdadero si el modelo se agregó correctamente, falso en caso contrario. */ addModel(modelDefinition) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); jsonData.tables.push(modelDefinition); this.saveModels(jsonData); this.models[modelDefinition.name] = new Model(modelDefinition); return true; } catch (error) { console.error('Error adding model:', error); return false; } } /** * @function updateModel * @description Actualiza un modelo existente en el archivo JSON y en la instancia de ModelManager. * @param {string} name - Nombre del modelo a actualizar. * @param {object} updatedDefinition - La nueva definición del modelo. * @returns {boolean} - Verdadero si el modelo se actualizó correctamente, falso si no se encontró o hubo un error. */ updateModel(name, updatedDefinition) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const index = jsonData.tables.findIndex(table => table.name === name); if (index !== -1) { jsonData.tables[index] = updatedDefinition; this.saveModels(jsonData); this.models[name] = new Model(updatedDefinition); return true; } else { console.warn(`Model with name "${name}" not found for update.`); return false; } } catch (error) { console.error(`Error updating model "${name}":`, error); return false; } } /** * @function deleteModel * @description Elimina un modelo del archivo JSON y de la instancia de ModelManager. * @param {string} name - Nombre del modelo a eliminar. * @returns {boolean} - Verdadero si el modelo se eliminó correctamente, falso si no se encontró o hubo un error. */ deleteModel(name) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const initialLength = jsonData.tables.length; jsonData.tables = jsonData.tables.filter(table => table.name !== name); if (jsonData.tables.length < initialLength) { this.saveModels(jsonData); delete this.models[name]; return true; } else { console.warn(`Model with name "${name}" not found for deletion.`); return false; } } catch (error) { console.error(`Error deleting model "${name}":`, error); return false; } } /** * @function addModelAttribute * @description Agrega un nuevo atributo a la definición de un modelo (fuera de la sección de columnas). * @param {string} modelName - Nombre del modelo al que se agregará el atributo. * @param {string} attributeName - Nombre del nuevo atributo (la clave). * @param {*} attributeValue - El valor del nuevo atributo. * @returns {boolean} - Verdadero si el atributo se agregó correctamente, falso si no se encontró el modelo o el atributo ya existe. */ addModelAttribute(modelName, attributeName, attributeValue) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const modelIndex = jsonData.tables.findIndex(table => table.name === modelName); if (modelIndex !== -1) { if (!jsonData.tables[modelIndex].hasOwnProperty(attributeName)) { jsonData.tables[modelIndex][attributeName] = attributeValue; this.saveModels(jsonData); this.models[modelName] = new Model(jsonData.tables[modelIndex]); return true; } else { console.warn(`Attribute "${attributeName}" already exists in model "${modelName}".`); return false; } } else { console.warn(`Model with name "${modelName}" not found for adding attribute.`); return false; } } catch (error) { console.error(`Error adding attribute "${attributeName}" to model "${modelName}":`, error); return false; } } /** * @function deleteModelAttribute * @description Elimina un atributo de la definición de un modelo (fuera de la sección de columnas). * @param {string} modelName - Nombre del modelo del que se eliminará el atributo. * @param {string} attributeName - Nombre del atributo a eliminar (la clave). * @returns {boolean} - Verdadero si el atributo se eliminó correctamente, falso si no se encontró el modelo o el atributo no existe. */ deleteModelAttribute(modelName, attributeName) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const modelIndex = jsonData.tables.findIndex(table => table.name === modelName); if (modelIndex !== -1 && jsonData.tables[modelIndex].hasOwnProperty(attributeName)) { delete jsonData.tables[modelIndex][attributeName]; this.saveModels(jsonData); this.models[modelName] = new Model(jsonData.tables[modelIndex]); return true; } else { console.warn(`Attribute "${attributeName}" not found in model "${modelName}".`); return false; } } catch (error) { console.error(`Error deleting attribute "${attributeName}" from model "${modelName}":`, error); return false; } } /** * @function updateModelAttribute * @description Actualiza el valor de un atributo existente en la definición de un modelo (fuera de la sección de columnas). * @param {string} modelName - Nombre del modelo cuyo atributo se actualizará. * @param {string} attributeName - Nombre del atributo a actualizar (la clave). * @param {*} attributeValue - El nuevo valor del atributo. * @returns {boolean} - Verdadero si el atributo se actualizó correctamente, falso si no se encontró el modelo o el atributo no existe. */ updateModelAttribute(modelName, attributeName, attributeValue) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const modelIndex = jsonData.tables.findIndex(table => table.name === modelName); if (modelIndex !== -1 && jsonData.tables[modelIndex].hasOwnProperty(attributeName)) { jsonData.tables[modelIndex][attributeName] = attributeValue; this.saveModels(jsonData); this.models[modelName] = new Model(jsonData.tables[modelIndex]); return true; } else { console.warn(`Attribute "${attributeName}" not found in model "${modelName}" for update.`); return false; } } catch (error) { console.error(`Error updating attribute "${attributeName}" in model "${modelName}":`, error); return false; } } /** * @function hasModelAttribute * @description Verifica si un atributo existe en la definición de un modelo (fuera de la sección de columnas). * @param {string} modelName - Nombre del modelo a verificar. * @param {string} attributeName - Nombre del atributo a buscar (la clave). * @returns {boolean} - Verdadero si el atributo existe en el modelo, falso si no se encontró el modelo o el atributo no existe. */ hasModelAttribute(modelName, attributeName) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const modelIndex = jsonData.tables.findIndex(table => table.name === modelName); if (modelIndex !== -1) { return jsonData.tables[modelIndex].hasOwnProperty(attributeName); } else { console.warn(`Model with name "${modelName}" not found for checking attribute.`); return false; } } catch (error) { console.error(`Error checking existence of attribute "${attributeName}" in model "${modelName}":`, error); return false; } } /** * @function addColumnAttribute * @description Agrega un nuevo atributo a una columna específica dentro de la definición de un modelo. * @param {string} modelName - Nombre del modelo al que pertenece la columna. * @param {string} columnName - Nombre de la columna a la que se agregará el atributo. * @param {string} attributeName - Nombre del nuevo atributo (la clave). * @param {*} attributeValue - El valor del nuevo atributo. * @returns {boolean} - Verdadero si el atributo se agregó correctamente, falso si no se encontró el modelo o la columna, o si el atributo ya existe. */ addColumnAttribute(modelName, columnName, attributeName, attributeValue) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const modelIndex = jsonData.tables.findIndex(table => table.name === modelName); if (modelIndex !== -1) { const column = jsonData.tables[modelIndex].columns.find(col => col.col === columnName); if (column) { if (!column.hasOwnProperty(attributeName)) { column[attributeName] = attributeValue; this.saveModels(jsonData); this.models[modelName] = new Model(jsonData.tables[modelIndex]); return true; } else { console.warn(`Attribute "${attributeName}" already exists in column "${columnName}" of model "${modelName}".`); return false; } } else { console.warn(`Column with name "${columnName}" not found in model "${modelName}".`); return false; } } else { console.warn(`Model with name "${modelName}" not found for adding column attribute.`); return false; } } catch (error) { console.error(`Error adding attribute "${attributeName}" to column "${columnName}" in model "${modelName}":`, error); return false; } } /** * @function editModelAttribute * @description Edita un atributo de una columna específica dentro de la definición de un modelo. * @param {string} modelName - Nombre del modelo al que pertenece la columna. * @param {string} columnName - Nombre de la columna cuyo atributo se va a editar. * @param {string} attributeName - Nombre del atributo a editar (la clave). * @param {*} attributeValue - El nuevo valor del atributo. * @returns {boolean} - Verdadero si el atributo se editó correctamente, falso si no se encontró el modelo o la columna. */ editModelAttribute(modelName, columnName, attributeName, attributeValue) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const modelIndex = jsonData.tables.findIndex(table => table.name === modelName); if (modelIndex !== -1) { const column = jsonData.tables[modelIndex].columns.find(col => col.col === columnName); if (column) { column[attributeName] = attributeValue; this.saveModels(jsonData); this.models[modelName] = new Model(jsonData.tables[modelIndex]); // Reinstanciar el modelo con la nueva definición return true; } else { console.warn(`Column with name "${columnName}" not found in model "${modelName}".`); return false; } } else { console.warn(`Model with name "${modelName}" not found for attribute editing.`); return false; } } catch (error) { console.error(`Error editing attribute "${attributeName}" of column "${columnName}" in model "${modelName}":`, error); return false; } } /** * @function deleteColumnAttribute * @description Elimina un atributo de una columna específica dentro de la definición de un modelo. * @param {string} modelName - Nombre del modelo al que pertenece la columna. * @param {string} columnName - Nombre de la columna cuyo atributo se va a eliminar. * @param {string} attributeName - Nombre del atributo a eliminar (la clave). * @returns {boolean} - Verdadero si el atributo se eliminó correctamente, falso si no se encontró el modelo, la columna o el atributo. */ deleteColumnAttribute(modelName, columnName, attributeName) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const modelIndex = jsonData.tables.findIndex(table => table.name === modelName); if (modelIndex !== -1) { const column = jsonData.tables[modelIndex].columns.find(col => col.col === columnName); if (column && column.hasOwnProperty(attributeName)) { delete column[attributeName]; this.saveModels(jsonData); this.models[modelName] = new Model(jsonData.tables[modelIndex]); return true; } else { console.warn(`Attribute "${attributeName}" not found in column "${columnName}" of model "${modelName}".`); return false; } } else { console.warn(`Model with name "${modelName}" not found for deleting column attribute.`); return false; } } catch (error) { console.error(`Error deleting attribute "${attributeName}" from column "${columnName}" in model "${modelName}":`, error); return false; } } /** * @function hasColumnAttribute * @description Verifica si una columna específica dentro de la definición de un modelo tiene un atributo determinado. * @param {string} modelName - Nombre del modelo al que pertenece la columna. * @param {string} columnName - Nombre de la columna a verificar. * @param {string} attributeName - Nombre del atributo a buscar (la clave). * @returns {boolean} - Verdadero si el atributo existe en la columna, falso si no se encontró el modelo o la columna, o si el atributo no existe. */ hasColumnAttribute(modelName, columnName, attributeName) { try { const data = fs.readFileSync(this.filePath, 'utf8'); const jsonData = JSON.parse(data); const modelIndex = jsonData.tables.findIndex(table => table.name === modelName); if (modelIndex !== -1) { const column = jsonData.tables[modelIndex].columns.find(col => col.col === columnName); if (column) { return column.hasOwnProperty(attributeName); } else { console.warn(`Column with name "${columnName}" not found in model "${modelName}".`); return false; } } else { console.warn(`Model with name "${modelName}" not found for checking column attribute.`); return false; } } catch (error) { console.error(`Error checking existence of attribute "${attributeName}" in column "${columnName}" of model "${modelName}":`, error); return false; } } /** * @private * @function saveModels * @description Guarda la estructura de modelos actualizada en el archivo JSON. * @param {object} jsonData - El objeto JSON con la lista de modelos. */ saveModels(jsonData) { fs.writeFileSync(this.filePath, JSON.stringify(jsonData, null, 2)); } } module.exports = ModelManager;