Passed
Pull Request — master (#1517)
by
unknown
02:40
created

internal/storage/postgres/tenantWriter.go   A

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 67
dl 0
loc 109
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A postgres.*TenantWriter.CreateTenant 0 25 3
A postgres.NewTenantWriter 0 4 1
B postgres.*TenantWriter.DeleteTenant 0 44 7
1
package postgres
2
3
import (
4
	"context"
5
	"errors"
6
	"fmt"
7
	"log/slog"
8
	"strings"
9
	"time"
10
11
	"github.com/jackc/pgx/v5"
12
13
	"go.opentelemetry.io/otel/codes"
14
15
	"google.golang.org/protobuf/types/known/timestamppb"
16
17
	"github.com/Permify/permify/internal/storage/postgres/utils"
18
	db "github.com/Permify/permify/pkg/database/postgres"
19
	base "github.com/Permify/permify/pkg/pb/base/v1"
20
)
21
22
// TenantWriter - Structure for Tenant Writer
23
type TenantWriter struct {
24
	database *db.Postgres
25
	// options
26
	txOptions pgx.TxOptions
27
}
28
29
// NewTenantWriter - Creates a new TenantWriter
30
func NewTenantWriter(database *db.Postgres) *TenantWriter {
31
	return &TenantWriter{
32
		database:  database,
33
		txOptions: pgx.TxOptions{IsoLevel: pgx.ReadCommitted, AccessMode: pgx.ReadWrite},
34
	}
35
}
36
37
// CreateTenant - Creates a new Tenant
38
func (w *TenantWriter) CreateTenant(ctx context.Context, id, name string) (result *base.Tenant, err error) {
39
	ctx, span := tracer.Start(ctx, "tenant-writer.create-tenant")
40
	defer span.End()
41
42
	slog.DebugContext(ctx, "creating new tenant", slog.Any("id", id), slog.Any("name", name))
43
44
	var createdAt time.Time
45
	err = w.database.WritePool.QueryRow(ctx, utils.InsertTenantTemplate, id, name).Scan(&createdAt)
46
	if err != nil {
47
		if strings.Contains(err.Error(), "duplicate key value") {
48
			span.RecordError(err)
49
			span.SetStatus(codes.Error, err.Error())
50
			slog.ErrorContext(ctx, "error encountered", slog.Any("error", err))
51
			return nil, errors.New(base.ErrorCode_ERROR_CODE_UNIQUE_CONSTRAINT.String())
52
		}
53
		return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_EXECUTION)
54
	}
55
56
	slog.DebugContext(ctx, "successfully created Tenant", slog.Any("id", id), slog.Any("name", name), slog.Any("created_at", createdAt))
57
58
	return &base.Tenant{
59
		Id:        id,
60
		Name:      name,
61
		CreatedAt: timestamppb.New(createdAt),
62
	}, nil
63
}
64
65
// DeleteTenant - Deletes a Tenant
66
func (w *TenantWriter) DeleteTenant(ctx context.Context, tenantID string) (result *base.Tenant, err error) {
67
	ctx, span := tracer.Start(ctx, "tenant-writer.delete-tenant")
68
	defer span.End()
69
70
	slog.DebugContext(ctx, "deleting tenant", slog.Any("tenant_id", tenantID))
71
72
	// Prepare batch operations for deleting tenant-related records from multiple tables
73
	tables := []string{"bundles", "relation_tuples", "attributes", "schema_definitions", "transactions"}
74
	batch := &pgx.Batch{}
75
76
	for _, table := range tables {
77
		query := fmt.Sprintf(utils.DeleteAllByTenantTemplate, table)
0 ignored issues
show
introduced by
can't check non-constant format in call to Sprintf
Loading history...
78
		batch.Queue(query, tenantID)
79
	}
80
81
	// Execute the batch of delete queries
82
	br := w.database.WritePool.SendBatch(ctx, batch)
83
	defer func() {
84
		if closeErr := br.Close(); closeErr != nil {
85
			if err == nil {
86
				err = closeErr
87
			}
88
		}
89
	}()
90
91
	if _, err = br.Exec(); err != nil {
92
		return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_EXECUTION)
93
	}
94
95
	// Retrieve the tenant details after deletion
96
	var name string
97
	var createdAt time.Time
98
	tenant := w.database.WritePool.QueryRow(ctx, utils.DeleteTenantTemplate, tenantID)
99
	if err != nil {
100
		return nil, utils.HandleError(ctx, span, err, base.ErrorCode_ERROR_CODE_EXECUTION)
101
	}
102
	tenant.Scan(&name, &createdAt)
103
104
	// Return the deleted tenant information
105
	return &base.Tenant{
106
		Id:        tenantID,
107
		Name:      name,
108
		CreatedAt: timestamppb.New(createdAt),
109
	}, nil
110
}
111