-
Notifications
You must be signed in to change notification settings - Fork 372
/
pair.go
125 lines (114 loc) · 3.31 KB
/
pair.go
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package common
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
// Pair defines an ID pair
type Pair struct {
left, right string
separator string
schema map[string]*schema.Schema
}
// NewPairID creates new ID pair
func NewPairID(left, right string) *Pair {
return NewPairSeparatedID(left, right, "|")
}
// NewPairSeparatedID creates new ID pair with a custom separator
func NewPairSeparatedID(left, right, separator string) *Pair {
return &Pair{
left: left,
right: right,
separator: separator,
schema: map[string]*schema.Schema{
left: {Type: schema.TypeString, ForceNew: true, Required: true},
right: {Type: schema.TypeString, ForceNew: true, Required: true},
},
}
}
// Schema sets custom schema
func (p *Pair) Schema(do func(map[string]*schema.Schema) map[string]*schema.Schema) *Pair {
p.schema = do(p.schema)
return p
}
// Unpack ID into two strings and set data
func (p *Pair) Unpack(d *schema.ResourceData) (string, string, error) {
id := d.Id()
parts := strings.SplitN(id, p.separator, 2)
if len(parts) != 2 {
d.SetId("")
return "", "", fmt.Errorf("invalid ID: %s", id)
}
if parts[0] == "" {
d.SetId("")
return "", "", fmt.Errorf("%s cannot be empty", p.left)
}
if parts[1] == "" {
d.SetId("")
return "", "", fmt.Errorf("%s cannot be empty", p.right)
}
err := p.setField(d, p.left, parts[0])
if err != nil {
return parts[0], parts[1], err
}
err = p.setField(d, p.right, parts[1])
return parts[0], parts[1], err
}
func (p *Pair) setField(d *schema.ResourceData, col, val string) error {
if p.schema[col].Type != schema.TypeInt {
return d.Set(col, val)
}
i64, err := strconv.ParseInt(val, 10, 64)
if err != nil {
return err
}
return d.Set(col, i64)
}
// Pack data attributes to ID
func (p *Pair) Pack(d *schema.ResourceData) {
d.SetId(fmt.Sprintf("%v%s%v", d.Get(p.left), p.separator, d.Get(p.right)))
}
// BindResource defines resource with simplified functions
type BindResource struct {
ReadContext func(ctx context.Context, left, right string, c *DatabricksClient) error
CreateContext func(ctx context.Context, left, right string, c *DatabricksClient) error
DeleteContext func(ctx context.Context, left, right string, c *DatabricksClient) error
}
// BindResource creates resource that relies on binding ID pair with simple schema & importer
func (p *Pair) BindResource(pr BindResource) *schema.Resource {
return Resource{
Schema: p.schema,
Read: func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error {
left, right, err := p.Unpack(d)
if err != nil {
return err
}
return pr.ReadContext(ctx, left, right, c)
},
Create: func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error {
left := d.Get(p.left).(string)
if left == "" {
return fmt.Errorf("%s cannot be empty", p.left)
}
right := d.Get(p.right).(string)
if right == "" {
return fmt.Errorf("%s cannot be empty", p.right)
}
err := pr.CreateContext(ctx, left, right, c)
if err != nil {
return err
}
p.Pack(d)
return nil
},
Delete: func(ctx context.Context, d *schema.ResourceData, c *DatabricksClient) error {
left, right, err := p.Unpack(d)
if err != nil {
return err
}
return pr.DeleteContext(ctx, left, right, c)
},
}.ToResource()
}