sless-primer/POSTGRES/code/js-idempotent/js_idempotent.js
2026-03-22 17:08:18 +04:00

59 lines
1.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 2026-03-21 — js-idempotent: INSERT с проверкой по idempotency_key.
// Повторный вызов с тем же key НЕ создаёт дубль — возвращает существующую запись.
// Тестирует: идемпотентность через SELECT ... FOR UPDATE + условный INSERT.
const { Client } = require('pg');
async function run(event) {
const key = String(event.idempotency_key ?? `auto-${Date.now()}`).slice(0, 200);
const title = String(event.title ?? key).slice(0, 255);
const client = new Client({
host: process.env.PGHOST,
port: parseInt(process.env.PGPORT ?? '5432'),
database: process.env.PGDATABASE,
user: process.env.PGUSER,
password: process.env.PGPASSWORD,
ssl: { rejectUnauthorized: false },
});
await client.connect();
try {
await client.query('BEGIN');
// Ищем существующую запись по title (используем как idempotency key)
const existing = await client.query(
'SELECT id, title, created_at FROM terraform_demo_table WHERE title = $1 LIMIT 1 FOR UPDATE',
[key]
);
let action, row;
if (existing.rows.length > 0) {
action = 'existing';
row = existing.rows[0];
} else {
const ins = await client.query(
'INSERT INTO terraform_demo_table (title) VALUES ($1) RETURNING id, title, created_at',
[key]
);
action = 'created';
row = ins.rows[0];
}
await client.query('COMMIT');
return {
action,
id: row.id,
title: row.title,
created_at: row.created_at,
idempotency_key: key,
};
} catch (e) {
await client.query('ROLLBACK');
throw e;
} finally {
await client.end();
}
}
module.exports = { run };