blob: b5f0a255279c53d142f510ae52dbfe5599734635 [file] [log] [blame]
divyadesai81bb7ba2020-03-11 11:45:23 +00001// Copyright 2016 The etcd Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package clientv3
16
17import (
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000018 pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
divyadesai81bb7ba2020-03-11 11:45:23 +000019)
20
21type CompareTarget int
22type CompareResult int
23
24const (
25 CompareVersion CompareTarget = iota
26 CompareCreated
27 CompareModified
28 CompareValue
29)
30
31type Cmp pb.Compare
32
33func Compare(cmp Cmp, result string, v interface{}) Cmp {
34 var r pb.Compare_CompareResult
35
36 switch result {
37 case "=":
38 r = pb.Compare_EQUAL
39 case "!=":
40 r = pb.Compare_NOT_EQUAL
41 case ">":
42 r = pb.Compare_GREATER
43 case "<":
44 r = pb.Compare_LESS
45 default:
46 panic("Unknown result op")
47 }
48
49 cmp.Result = r
50 switch cmp.Target {
51 case pb.Compare_VALUE:
52 val, ok := v.(string)
53 if !ok {
54 panic("bad compare value")
55 }
56 cmp.TargetUnion = &pb.Compare_Value{Value: []byte(val)}
57 case pb.Compare_VERSION:
58 cmp.TargetUnion = &pb.Compare_Version{Version: mustInt64(v)}
59 case pb.Compare_CREATE:
60 cmp.TargetUnion = &pb.Compare_CreateRevision{CreateRevision: mustInt64(v)}
61 case pb.Compare_MOD:
62 cmp.TargetUnion = &pb.Compare_ModRevision{ModRevision: mustInt64(v)}
63 case pb.Compare_LEASE:
64 cmp.TargetUnion = &pb.Compare_Lease{Lease: mustInt64orLeaseID(v)}
65 default:
66 panic("Unknown compare type")
67 }
68 return cmp
69}
70
71func Value(key string) Cmp {
72 return Cmp{Key: []byte(key), Target: pb.Compare_VALUE}
73}
74
75func Version(key string) Cmp {
76 return Cmp{Key: []byte(key), Target: pb.Compare_VERSION}
77}
78
79func CreateRevision(key string) Cmp {
80 return Cmp{Key: []byte(key), Target: pb.Compare_CREATE}
81}
82
83func ModRevision(key string) Cmp {
84 return Cmp{Key: []byte(key), Target: pb.Compare_MOD}
85}
86
87// LeaseValue compares a key's LeaseID to a value of your choosing. The empty
88// LeaseID is 0, otherwise known as `NoLease`.
89func LeaseValue(key string) Cmp {
90 return Cmp{Key: []byte(key), Target: pb.Compare_LEASE}
91}
92
93// KeyBytes returns the byte slice holding with the comparison key.
94func (cmp *Cmp) KeyBytes() []byte { return cmp.Key }
95
96// WithKeyBytes sets the byte slice for the comparison key.
97func (cmp *Cmp) WithKeyBytes(key []byte) { cmp.Key = key }
98
99// ValueBytes returns the byte slice holding the comparison value, if any.
100func (cmp *Cmp) ValueBytes() []byte {
101 if tu, ok := cmp.TargetUnion.(*pb.Compare_Value); ok {
102 return tu.Value
103 }
104 return nil
105}
106
107// WithValueBytes sets the byte slice for the comparison's value.
108func (cmp *Cmp) WithValueBytes(v []byte) { cmp.TargetUnion.(*pb.Compare_Value).Value = v }
109
110// WithRange sets the comparison to scan the range [key, end).
111func (cmp Cmp) WithRange(end string) Cmp {
112 cmp.RangeEnd = []byte(end)
113 return cmp
114}
115
116// WithPrefix sets the comparison to scan all keys prefixed by the key.
117func (cmp Cmp) WithPrefix() Cmp {
118 cmp.RangeEnd = getPrefix(cmp.Key)
119 return cmp
120}
121
122// mustInt64 panics if val isn't an int or int64. It returns an int64 otherwise.
123func mustInt64(val interface{}) int64 {
124 if v, ok := val.(int64); ok {
125 return v
126 }
127 if v, ok := val.(int); ok {
128 return int64(v)
129 }
130 panic("bad value")
131}
132
133// mustInt64orLeaseID panics if val isn't a LeaseID, int or int64. It returns an
134// int64 otherwise.
135func mustInt64orLeaseID(val interface{}) int64 {
136 if v, ok := val.(LeaseID); ok {
137 return int64(v)
138 }
139 return mustInt64(val)
140}