handle() → run_sql() (sql_runner.py, entrypoint: sql_runner.run_sql) handle() → crud() (notes_crud.py, entrypoint: notes_crud.crud) handle() → list_notes() (notes_list.py, entrypoint: notes_list.list_notes)
82 lines
3.2 KiB
Python
82 lines
3.2 KiB
Python
# 2026-03-09
|
|
# notes_crud.py — CRUD роутер для таблицы notes.
|
|
#
|
|
# Назначение: единая функция, которая обрабатывает все операции с записями.
|
|
# Роутинг осуществляется по sub-path URL (event._path), который runtime
|
|
# берёт из входящего HTTP-запроса и добавляет в event автоматически.
|
|
#
|
|
# Доступные маршруты (все POST):
|
|
# /fn/default/notes/add?title=...&body=... → создать запись
|
|
# /fn/default/notes/update?id=1&title=...&body=... → обновить запись
|
|
# /fn/default/notes/delete?id=1 → удалить запись
|
|
#
|
|
# Параметры берутся из query string (event._query) или из тела запроса (event).
|
|
# event._path и event._query добавляет Python runtime (server.py) автоматически.
|
|
import os
|
|
import psycopg2
|
|
import psycopg2.extras
|
|
|
|
|
|
def crud(event):
|
|
dsn = os.environ['PG_DSN']
|
|
# sub-path без ведущего слэша: "add", "update", "delete"
|
|
action = event.get('_path', '/').strip('/')
|
|
q = event.get('_query', {})
|
|
|
|
conn = psycopg2.connect(dsn)
|
|
try:
|
|
cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
|
|
|
|
if action == 'add':
|
|
title = q.get('title') or event.get('title', '')
|
|
body = q.get('body') or event.get('body', '')
|
|
if not title:
|
|
return {'error': 'title is required'}
|
|
cur.execute(
|
|
"INSERT INTO notes (title, body) VALUES (%s, %s)"
|
|
" RETURNING id, title, body, created_at::text",
|
|
(title, body)
|
|
)
|
|
row = cur.fetchone()
|
|
conn.commit()
|
|
return dict(row)
|
|
|
|
elif action == 'update':
|
|
id_ = q.get('id') or event.get('id')
|
|
if not id_:
|
|
return {'error': 'id is required'}
|
|
title = q.get('title') or event.get('title', '')
|
|
body = q.get('body') or event.get('body', '')
|
|
cur.execute(
|
|
"UPDATE notes SET title=%s, body=%s WHERE id=%s"
|
|
" RETURNING id, title, body, created_at::text",
|
|
(title, body, int(id_))
|
|
)
|
|
row = cur.fetchone()
|
|
conn.commit()
|
|
return dict(row) if row else {'error': 'not found'}
|
|
|
|
elif action == 'delete':
|
|
id_ = q.get('id') or event.get('id')
|
|
if not id_:
|
|
return {'error': 'id is required'}
|
|
cur.execute(
|
|
"DELETE FROM notes WHERE id=%s RETURNING id",
|
|
(int(id_),)
|
|
)
|
|
row = cur.fetchone()
|
|
conn.commit()
|
|
return {'deleted': row['id']} if row else {'error': 'not found'}
|
|
|
|
else:
|
|
return {
|
|
'error': f'unknown action: /{action}',
|
|
'hint': 'use /add?title=...&body=..., /update?id=X&title=...&body=..., /delete?id=X'
|
|
}
|
|
|
|
except Exception as e:
|
|
conn.rollback()
|
|
return {'error': str(e)}
|
|
finally:
|
|
conn.close()
|