MCPcopy Create free account
hub / github.com/Mnexa-AI/e2a / applyOne

Function applyOne

internal/identity/migrate.go:350–397  ·  view source on GitHub ↗

applyOne reads a migration file and applies it. For migrations without the no-transaction directive: SQL + tracker insert run in a single transaction so a partial-failure migration is safe to retry. Tx isolation defaults to READ COMMITTED, which is correct here (we don't want SERIALIZABLE forcing r

(ctx context.Context, conn *pgxpool.Conn, fsys fs.FS, name string)

Source from the content-addressed store, hash-verified

348// itself; the directive is opt-in for the specific Postgres features
349// that require it.
350func applyOne(ctx context.Context, conn *pgxpool.Conn, fsys fs.FS, name string) error {
351 body, err := fs.ReadFile(fsys, name)
352 if err != nil {
353 return fmt.Errorf("read %s: %w", name, err)
354 }
355
356 if hasNoTransactionDirective(string(body)) {
357 // pgx's simple protocol sends multi-statement strings to the
358 // server as a single Query message, which Postgres wraps in an
359 // implicit transaction — defeating the directive's purpose and
360 // surfacing as a confusing "cannot run inside a transaction
361 // block" error from the actual offending statement. Catch it
362 // here with a clear message.
363 if looksMultiStatement(string(body)) {
364 return fmt.Errorf("migration %s uses -- e2a:no-transaction but contains multiple statements; split into separate files (one per statement)", name)
365 }
366 if _, err := conn.Exec(ctx, string(body)); err != nil {
367 return fmt.Errorf("exec migration (no-transaction): %w", err)
368 }
369 if _, err := conn.Exec(ctx,
370 "INSERT INTO schema_migrations (filename) VALUES ($1) ON CONFLICT DO NOTHING",
371 name,
372 ); err != nil {
373 return fmt.Errorf("record migration: %w", err)
374 }
375 return nil
376 }
377
378 tx, err := conn.BeginTx(ctx, pgx.TxOptions{})
379 if err != nil {
380 return fmt.Errorf("begin tx: %w", err)
381 }
382 defer func() { _ = tx.Rollback(ctx) }()
383
384 if _, err := tx.Exec(ctx, string(body)); err != nil {
385 return fmt.Errorf("exec migration: %w", err)
386 }
387 if _, err := tx.Exec(ctx,
388 "INSERT INTO schema_migrations (filename) VALUES ($1) ON CONFLICT DO NOTHING",
389 name,
390 ); err != nil {
391 return fmt.Errorf("record migration: %w", err)
392 }
393 if err := tx.Commit(ctx); err != nil {
394 return fmt.Errorf("commit: %w", err)
395 }
396 return nil
397}

Callers 1

RunMigrationsFunction · 0.85

Calls 5

looksMultiStatementFunction · 0.85
RollbackMethod · 0.80
CommitMethod · 0.80
ExecMethod · 0.65

Tested by

no test coverage detected