plugin-postgresql-connector
Version:
NocoBase plugin for connecting to external PostgreSQL databases
199 lines • 6.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SavedQuery = void 0;
const sequelize_1 = require("sequelize");
class SavedQuery extends sequelize_1.Model {
static init(database) {
super.init({
id: {
type: sequelize_1.DataTypes.UUID,
defaultValue: sequelize_1.DataTypes.UUIDV4,
primaryKey: true,
},
connectionId: {
type: sequelize_1.DataTypes.UUID,
allowNull: false,
references: {
model: 'postgresql_connections',
key: 'id',
},
validate: {
notEmpty: true,
},
},
name: {
type: sequelize_1.DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true,
len: [1, 255],
},
},
query: {
type: sequelize_1.DataTypes.TEXT,
allowNull: false,
validate: {
notEmpty: true,
},
},
queryType: {
type: sequelize_1.DataTypes.ENUM('SELECT', 'INSERT', 'UPDATE', 'DELETE', 'PROCEDURE', 'FUNCTION', 'VIEW', 'OTHER'),
allowNull: false,
defaultValue: 'SELECT',
},
parameters: {
type: sequelize_1.DataTypes.JSON,
defaultValue: [],
validate: {
isValidParameters(value) {
if (!Array.isArray(value)) {
throw new Error('Parameters must be an array');
}
},
},
},
description: {
type: sequelize_1.DataTypes.TEXT,
allowNull: true,
},
category: {
type: sequelize_1.DataTypes.STRING,
allowNull: true,
defaultValue: 'general',
},
tags: {
type: sequelize_1.DataTypes.JSON,
defaultValue: [],
validate: {
isValidTags(value) {
if (!Array.isArray(value)) {
throw new Error('Tags must be an array');
}
},
},
},
isPublic: {
type: sequelize_1.DataTypes.BOOLEAN,
defaultValue: false,
},
executionCount: {
type: sequelize_1.DataTypes.INTEGER,
defaultValue: 0,
},
lastExecutedAt: {
type: sequelize_1.DataTypes.DATE,
allowNull: true,
},
createdBy: {
type: sequelize_1.DataTypes.UUID,
allowNull: true, // For future user association
},
createdAt: {
type: sequelize_1.DataTypes.DATE,
defaultValue: sequelize_1.DataTypes.NOW,
},
updatedAt: {
type: sequelize_1.DataTypes.DATE,
defaultValue: sequelize_1.DataTypes.NOW,
},
}, {
sequelize: database.sequelize,
modelName: 'SavedQuery',
tableName: 'postgresql_saved_queries',
timestamps: true,
paranoid: true, // Soft delete
indexes: [
{
fields: ['connectionId'],
},
{
fields: ['queryType'],
},
{
fields: ['category'],
},
{
fields: ['isPublic'],
},
{
fields: ['createdBy'],
},
{
fields: ['name', 'connectionId'],
unique: true,
where: {
deletedAt: null,
},
},
],
});
}
static associate(models) {
this.belongsTo(models.Connection, {
foreignKey: 'connectionId',
as: 'connection',
onDelete: 'CASCADE',
});
// Future: User association
// this.belongsTo(models.User, {
// foreignKey: 'createdBy',
// as: 'creator',
// });
}
// Instance methods
async execute() {
// This will be implemented in service layer
return {};
}
incrementExecutionCount() {
this.setDataValue('executionCount', this.getDataValue('executionCount') + 1);
this.setDataValue('lastExecutedAt', new Date());
}
addTag(tag) {
const tags = this.getDataValue('tags') || [];
if (!tags.includes(tag)) {
tags.push(tag);
this.setDataValue('tags', tags);
}
}
removeTag(tag) {
const tags = this.getDataValue('tags') || [];
const filteredTags = tags.filter((t) => t !== tag);
this.setDataValue('tags', filteredTags);
}
getParameterNames() {
const query = this.getDataValue('query');
const parameterRegex = /\$\{(\w+)\}/g;
const parameters = [];
let match;
while ((match = parameterRegex.exec(query)) !== null) {
if (!parameters.includes(match[1])) {
parameters.push(match[1]);
}
}
return parameters;
}
// Validate query syntax
validateQuery() {
const query = this.getDataValue('query').trim();
const errors = [];
if (!query) {
errors.push('Query cannot be empty');
}
// Basic SQL validation
const dangerousKeywords = ['DROP', 'TRUNCATE', 'ALTER', 'CREATE USER', 'GRANT', 'REVOKE'];
const upperQuery = query.toUpperCase();
for (const keyword of dangerousKeywords) {
if (upperQuery.includes(keyword)) {
errors.push(`Potentially dangerous keyword detected: ${keyword}`);
}
}
return {
isValid: errors.length === 0,
errors,
};
}
}
exports.SavedQuery = SavedQuery;
exports.default = SavedQuery;
//# sourceMappingURL=SavedQuery.js.map