From 0298eeaa84b1472c628b84f6f9a9edc977fcd1a2 Mon Sep 17 00:00:00 2001 From: Bel LaPointe <153096461+breel-render@users.noreply.github.com> Date: Thu, 20 Nov 2025 09:49:17 -0700 Subject: [PATCH] impl pg-lo-dmeo --- cmd/pg-lo-demo/main.go | 60 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/cmd/pg-lo-demo/main.go b/cmd/pg-lo-demo/main.go index b160a8d..75a28f7 100644 --- a/cmd/pg-lo-demo/main.go +++ b/cmd/pg-lo-demo/main.go @@ -1,9 +1,11 @@ package main import ( + "bytes" "context" "database/sql" "flag" + "fmt" "os" "pg/src/with" @@ -25,8 +27,60 @@ func run(ctx context.Context) error { } return with.PSQL(ctx, *c, func(pg *sql.DB) error { - // SELECT lo_creat(-1); - // SELECT pg_catalog.lowrite(0, '\\037\\213\\010\\000\\000\\000\\000\\000\\000\\000\\245\\220;n\\3030\\014') - return ctx.Err() + cleanup := func() error { + rows, err := pg.QueryContext(ctx, `SELECT oid FROM oids`) + if err != nil { + return nil + } + defer rows.Close() + for rows.Next() { + var oid any + if err := rows.Scan(&oid); err != nil { + return err + } + pg.ExecContext(ctx, `SELECT lo_unlink($1)`, oid) + } + return rows.Err() + } + defer cleanup() + + if err := cleanup(); err != nil { + return fmt.Errorf("failed initial cleanup: %w", err) + } + + if _, err := pg.ExecContext(ctx, ` + DROP TABLE IF EXISTS oids; + CREATE TABLE IF NOT EXISTS oids (id INTEGER PRIMARY KEY, oid OID); + `); err != nil { + return fmt.Errorf("failed initial table setup: %w", err) + } + + if _, err := pg.ExecContext(ctx, ` + INSERT INTO oids ( + id, + oid + ) + VALUES ( + 1, + lo_from_bytea( + 0, + $1 + ) + ) ON CONFLICT DO NOTHING + `, []byte("hello world")); err != nil { + return fmt.Errorf("failed lo_from_bytea: %w", err) + } + + var got []byte + row := pg.QueryRowContext(ctx, `SELECT lo_get((SELECT oid FROM oids WHERE id=1))`) + if err := row.Err(); err != nil { + return err + } else if err := row.Scan(&got); err != nil { + return err + } else if !bytes.Equal(got, []byte("hello world")) { + return fmt.Errorf("weird lo_get: %q", got) + } + + return cleanup() }) }