fintual-backend-devops-go / harness / fixtures.go
fixtures.go
Raw
package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/jackc/pgx/v5"
)

const fixtureVersion = "contract-v1"

// Run outside timed sections. Equivalent rows alone do not imply equivalent
// planner statistics or index-only-scan visibility after bulk load/TRUNCATE.
func prepareTables(ctx context.Context, c *pgx.Conn) error {
	if err := guard(ctx, c); err != nil {
		return err
	}
	_, err := c.Exec(ctx, "VACUUM (ANALYZE) blog_user,blog_tag,blog_post,blog_post_tags,blog_comment")
	return err
}

func openDB(ctx context.Context, dsn string) (*pgx.Conn, error) {
	c, err := pgx.Connect(ctx, dsn)
	if err != nil {
		return nil, err
	}
	var name string
	if err = c.QueryRow(ctx, "SELECT current_database()").Scan(&name); err != nil {
		c.Close(ctx)
		return nil, err
	}
	if !strings.HasPrefix(name, "assignment_harness_") {
		c.Close(ctx)
		return nil, fmt.Errorf("refusing non-task database %q", name)
	}
	return c, nil
}

func claim(ctx context.Context, c *pgx.Conn) error {
	var owner bool
	err := c.QueryRow(ctx, `SELECT pg_get_userbyid(datdba)=current_user FROM pg_database WHERE datname=current_database()`).Scan(&owner)
	if err != nil {
		return err
	}
	if !owner {
		return fmt.Errorf("task database must belong to current user")
	}
	var markerExists bool
	if err = c.QueryRow(ctx, `SELECT to_regclass('public.harness_ownership') IS NOT NULL`).Scan(&markerExists); err != nil {
		return err
	}
	if !markerExists {
		for _, table := range []string{"blog_user", "blog_tag", "blog_post", "blog_post_tags", "blog_comment"} {
			var exists bool
			if err = c.QueryRow(ctx, "SELECT EXISTS(SELECT 1 FROM "+table+" LIMIT 1)").Scan(&exists); err != nil {
				return err
			}
			if exists {
				return fmt.Errorf("refusing to claim populated unmarked database (%s)", table)
			}
		}
	}
	_, err = c.Exec(ctx, `CREATE TABLE IF NOT EXISTS harness_ownership (id boolean PRIMARY KEY CHECK(id), marker text NOT NULL);
 INSERT INTO harness_ownership VALUES(true,'backend-devops-contract-v1') ON CONFLICT DO NOTHING`)
	return err
}

func guard(ctx context.Context, c *pgx.Conn) error {
	var owner bool
	if err := c.QueryRow(ctx, `SELECT pg_get_userbyid(datdba)=current_user FROM pg_database WHERE datname=current_database()`).Scan(&owner); err != nil {
		return err
	}
	if !owner {
		return fmt.Errorf("task database is not owned by current user")
	}
	var marker string
	if err := c.QueryRow(ctx, `SELECT marker FROM harness_ownership WHERE id=true`).Scan(&marker); err != nil {
		return err
	}
	if marker != "backend-devops-contract-v1" {
		return fmt.Errorf("wrong task ownership marker")
	}
	return nil
}

func fixture(ctx context.Context, c *pgx.Conn) error {
	if err := guard(ctx, c); err != nil {
		return err
	}
	_, err := c.Exec(ctx, `
 TRUNCATE blog_comment,blog_post_tags,blog_post,blog_tag,blog_user RESTART IDENTITY;
 INSERT INTO blog_user(username,email,display_name,bio,created_at) VALUES
 ('alice','alice@example.com','Alice','Author biography','2024-01-01Z'),
 ('bob','duplicate@example.com','Bob','','2024-01-01Z'),
 ('carol','duplicate@example.com','Carol','','2024-01-01Z');
 INSERT INTO blog_tag(name,slug,created_at) VALUES
 ('Python','python','2024-01-01Z'),('Django','django','2024-01-01Z'),('Empty','empty','2024-01-01Z');
 INSERT INTO blog_post(title,body,is_published,view_count,created_at,updated_at,author_id) VALUES
 ('Hello Python','A body with 100% and under_score and café',true,7,'2024-01-01Z','2024-01-01Z',1),
 ('Secret draft','python hidden',false,0,'2024-01-02Z','2024-01-02Z',1),
 ('Unicode café 🚀','PYTHON and backslash \\',true,2,'2024-01-03Z','2024-01-03Z',2),
 ('Tied date','unrelated content',true,0,'2024-01-03Z','2024-01-03Z',3);
 INSERT INTO blog_post_tags(post_id,tag_id) VALUES(1,2),(1,1),(2,1),(3,1);
 INSERT INTO blog_comment(body,created_at,post_id,author_id) VALUES
 ('First','2024-02-01Z',1,2),('Second café','2024-02-01Z',1,1),('Draft comment','2024-02-02Z',2,3);
 `)
	return err
}

func state(ctx context.Context, c *pgx.Conn) (map[string]any, error) {
	result := map[string]any{}
	for _, table := range []string{"blog_user", "blog_tag", "blog_post", "blog_post_tags", "blog_comment"} {
		rows, err := c.Query(ctx, "SELECT row_to_json(t)::text FROM "+table+" t ORDER BY id")
		if err != nil {
			return nil, err
		}
		values := []any{}
		for rows.Next() {
			var raw string
			if err = rows.Scan(&raw); err != nil {
				rows.Close()
				return nil, err
			}
			v, err := decode([]byte(raw))
			if err != nil {
				rows.Close()
				return nil, err
			}
			values = append(values, v)
		}
		err = rows.Err()
		rows.Close()
		if err != nil {
			return nil, err
		}
		result[table] = values
		var last int64
		var called bool
		if err = c.QueryRow(ctx, "SELECT last_value,is_called FROM "+table+"_id_seq").Scan(&last, &called); err != nil {
			return nil, err
		}
		result[table+"_sequence"] = map[string]any{"last_value": last, "is_called": called}
	}
	return result, nil
}