stillbox/pkg/database/partitions.go

87 lines
2.6 KiB
Go

package database
import (
"context"
"time"
)
type partitionsQuerier interface {
GetTablePartitions(ctx context.Context, schemaName, tableName string) ([]string, error)
CreatePartition(ctx context.Context, parentTable, partitionName string, start, end time.Time) error
DetachPartition(ctx context.Context, partitionName string) error
DropPartition(ctx context.Context, partitionName string) error
}
func (q *Queries) GetTablePartitions(ctx context.Context, schemaName, tableName string) ([]string, error) {
const query = `SELECT child.relname
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
JOIN pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace
JOIN pg_namespace nmsp_child ON nmsp_child.oid = child.relnamespace
WHERE
nmsp_parent.nspname = nmsp_child.nspname -- parent and child schemas are the same
AND nmsp_child.nspname = $2 -- schemaName
AND parent.relname = $1;` // tableName
rows, err := q.db.Query(ctx, query, schemaName, tableName)
if err != nil {
return nil, err
}
defer rows.Close()
var partitions []string
for rows.Next() {
var partitionName string
if err := rows.Scan(&partitionName); err != nil {
return nil, err
}
partitions = append(partitions, partitionName)
}
if err := rows.Err(); err != nil {
return nil, err
}
return partitions, nil
}
func (q *Queries) CreatePartition(ctx context.Context, parentTable, partitionName string, start, end time.Time) error {
_, err := q.db.Exec(ctx, `CREATE TABLE $1 PARTITION OF $2 FOR VALUES FROM ($2) TO ($3);`, partitionName, parentTable, start, end)
return err
}
func (q *Queries) DropPartition(ctx context.Context, partitionName string) error {
_, err := q.db.Exec(ctx, `DROP TABLE $1;`, partitionName)
return err
}
func (q *Queries) DetachPartition(ctx context.Context, partitionName string) error {
_, err := q.db.Exec(ctx, `ALTER TABLE $1 DETACH PARTITION;`, partitionName)
return err
}
/*
func (q *Queries) SweepCalls(ctx context.context, start, end time.Time) {
const -- name: SweepCalls :exec
BEGIN;
WITH to_sweep AS (
SELECT * FROM calls
JOIN incidents_calls ic ON ic.call_id = calls.id
WHERE calls.call_date >= @range_start AND calls.call_date < @range_end
) INSERT INTO swept_calls SELECT * FROM todelete;
WITH to_sweep AS (
SELECT id FROM calls
JOIN incidents_calls ic ON ic.call_id = calls.id
WHERE calls.call_date >= @range_start AND calls.call_date < @range_end
) UPDATE incidents_calls
SET
swept_call_id = call_id,
calls_tbl_id = NULL
WHERE call_id IN (SELECT id FROM to_sweep);
COMMIT;}
*/