This commit is contained in:
2026-03-18 17:19:02 +07:00
parent 9fa65ba4af
commit d1ba0eb58b
3 changed files with 96 additions and 148 deletions

117
server.js
View File

@@ -179,8 +179,8 @@ app.get('/api/tables/:tableName/data', requireAuth, async (req, res) => {
try {
let whereClause = '';
let params = [limit, offset];
let paramIndex = 3; // $1=limit, $2=offset, $3+ for conditions
let params = [];
let paramIndex = 1;
// Search
if (search) {
@@ -199,68 +199,23 @@ app.get('/api/tables/:tableName/data', requireAuth, async (req, res) => {
}
// Filters
if (filters.length > 0) {
const filterConditions = filters.map(filter => {
const { column, operator, value } = filter;
let condition = '';
switch (operator) {
case '=':
condition = `"${column}" = $${paramIndex}`;
params.push(value);
paramIndex++;
break;
case '!=':
condition = `"${column}" != $${paramIndex}`;
params.push(value);
paramIndex++;
break;
case '>':
condition = `"${column}" > $${paramIndex}`;
params.push(value);
paramIndex++;
break;
case '<':
condition = `"${column}" < $${paramIndex}`;
params.push(value);
paramIndex++;
break;
case '>=':
condition = `"${column}" >= $${paramIndex}`;
params.push(value);
paramIndex++;
break;
case '<=':
condition = `"${column}" <= $${paramIndex}`;
params.push(value);
paramIndex++;
break;
case 'LIKE':
condition = `"${column}" LIKE $${paramIndex}`;
params.push(`%${value}%`);
paramIndex++;
break;
case 'ILIKE':
condition = `"${column}" ILIKE $${paramIndex}`;
params.push(`%${value}%`);
paramIndex++;
break;
case 'IS NULL':
condition = `"${column}" IS NULL`;
break;
case 'IS NOT NULL':
condition = `"${column}" IS NOT NULL`;
break;
if (filters && typeof filters === 'object') {
const filterConditions = Object.entries(filters).map(([column, value]) => {
if (value && value.trim()) {
params.push(`%${value}%`);
paramIndex++;
return `"${column}" ILIKE $${paramIndex - 1}`;
}
return condition;
}).filter(c => c).join(' AND ');
return null;
}).filter(c => c);
whereClause = whereClause ? `${whereClause} AND ${filterConditions}` : `WHERE ${filterConditions}`;
if (filterConditions.length > 0) {
whereClause = whereClause ? `${whereClause} AND ${filterConditions.join(' AND ')}` : `WHERE ${filterConditions.join(' AND ')}`;
}
}
// Get total count
const countResult = await pool.query(`SELECT COUNT(*) as total FROM "${tableName}" ${whereClause}`, params.slice(2));
const countResult = await pool.query(`SELECT COUNT(*) as total FROM "${tableName}" ${whereClause}`, params);
const total = parseInt(countResult.rows[0].total);
// Build ORDER BY
@@ -274,8 +229,8 @@ app.get('/api/tables/:tableName/data', requireAuth, async (req, res) => {
SELECT * FROM "${tableName}"
${whereClause}
${orderBy}
LIMIT $1 OFFSET $2
`, params);
LIMIT $${paramIndex} OFFSET $${paramIndex + 1}
`, [...params, limit, offset]);
res.json({
data: result.rows,
@@ -358,11 +313,43 @@ app.post('/api/tables/:tableName/records', requireAuth, async (req, res) => {
const { tableName } = req.params;
const data = req.body;
const columns = Object.keys(data);
const values = Object.values(data);
const placeholders = values.map((_, i) => `$${i + 1}`).join(', ');
try {
// Get table structure to check types
const structureResult = await pool.query(`
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = $1 AND table_schema = 'public'
`, [tableName]);
const structure = structureResult.rows;
// Filter out empty UUIDs and generate if needed
const filteredData = {};
for (const [key, value] of Object.entries(data)) {
const colInfo = structure.find(col => col.column_name === key);
if (colInfo && colInfo.data_type === 'uuid') {
if (!value || value.trim() === '') {
// Generate UUID for empty UUID fields
filteredData[key] = require('crypto').randomUUID();
} else {
// Validate UUID
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
if (uuidRegex.test(value)) {
filteredData[key] = value;
} else {
// Invalid UUID, generate new one
filteredData[key] = require('crypto').randomUUID();
}
}
} else if (value !== '') {
filteredData[key] = value;
}
}
const columns = Object.keys(filteredData);
const values = Object.values(filteredData);
const placeholders = values.map((_, i) => `$${i + 1}`).join(', ');
const sql = `INSERT INTO "${tableName}" (${columns.map(c => `"${c}"`).join(', ')}) VALUES (${placeholders}) RETURNING *`;
const result = await pool.query(sql, values);
res.json({ success: true, data: result.rows[0] });