aboutsummaryrefslogtreecommitdiff
path: root/internal/plan_test.go
blob: 827c6e46074b366cc5155db39b0bd6735bf507bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// SPDX-FileCopyrightText: 2026 Stefan Majewsky <majewsky@gmx.net>
// SPDX-License-Identifier: Apache-2.0

package internal_test

import (
	"reflect"
	"testing"
	"time"

	"go.xyrillian.de/oblast/info"
	"go.xyrillian.de/oblast/internal"
	"go.xyrillian.de/oblast/internal/assert"
)

func TestPlanFieldTraversal(t *testing.T) {
	type Log struct {
		info.TableNameIs  `db:"log_entries"`
		info.PrimaryKeyIs `db:"id"`
		ID                int64     `db:"id,auto"`
		CreatedAt         time.Time `db:"created_at"`
		Message           string    `db:"message"`
		private1          bool      `db:"private1"` //nolint:unused
	}

	// assert on interface implementations
	var (
		_ info.IsTable               = Log{}
		_ info.IsTableWithPrimaryKey = Log{}
	)

	// check that the plan for Log:
	// 1. has no IndexByColumnName entries for marker types
	// 2. ignores "private1" because it cannot be written through reflection
	// 3. recognizes "id" as an autofilled column
	plan, err := internal.BuildPlan(reflect.TypeFor[Log](), internal.PostgresDialect{})
	if err != nil {
		t.Error(err)
	}
	assert.Equal(t, plan.TableName, "log_entries")
	assert.DeepEqual(t, plan.PrimaryKeyColumns, []string{"id"})
	assert.DeepEqual(t, plan.AutoColumns, []string{"id"})
	assert.DeepEqual(t, plan.IndexByColumnName, map[string][]int{
		"id":         {2},
		"created_at": {3},
		"message":    {4},
	})

	type record struct {
		Log
		Keks     bool `db:"keks"`
		private2 bool `db:"private2"` //nolint:unused
	}

	// check that the plan for record:
	// 1. works at all, even though it as a whole is an unexported type
	// 2. traverses into Log and includes all of its fields as well
	// 3. completely ignores the marker types in type Log
	plan, err = internal.BuildPlan(reflect.TypeFor[record](), internal.PostgresDialect{})
	if err != nil {
		t.Error(err)
	}
	assert.Equal(t, plan.TableName, "")
	assert.DeepEqual(t, plan.PrimaryKeyColumns, nil)
	assert.DeepEqual(t, plan.AutoColumns, []string{"id"}) // this is okay, it does not bear significance in practice since no queries are generated
	assert.DeepEqual(t, plan.IndexByColumnName, map[string][]int{
		"id":         {0, 2},
		"created_at": {0, 3},
		"message":    {0, 4},
		"keks":       {1},
	})
}