github.com/mitranim/sqlb@v0.7.2/sqlb_array.go (about) 1 package sqlb 2 3 import "database/sql/driver" 4 5 /* 6 Intermediary tool for implementing SQL array encoding. Has the same behavior as 7 `CommaAppender`, but the text output is always enclosed in `{}`. 8 */ 9 type ArrayAppender[A AppenderTo] []A 10 11 /* 12 Implement `fmt.Stringer`. Same as `CommaAppender.String`, but the output is 13 always enclosed in `{}`. 14 */ 15 func (self ArrayAppender[_]) String() string { return AppenderString(&self) } 16 17 /* 18 Implement `AppenderTo`. Same as `CommaAppender.AppendTo`, but the output is always 19 enclosed in `{}`. 20 */ 21 func (self ArrayAppender[A]) AppendTo(buf []byte) []byte { 22 buf = append(buf, `{`...) 23 buf = CommaAppender[A](self).AppendTo(buf) 24 buf = append(buf, `}`...) 25 return buf 26 } 27 28 func (self ArrayAppender[_]) Get() any { return self.String() } 29 30 func (self ArrayAppender[_]) Value() (driver.Value, error) { return self.Get(), nil } 31 32 /* 33 Intermediary tool for implementing SQL array encoding. Combines multiple 34 arbitrary text encoders. On demand (on a call to `.AppendTo` or `.String`), 35 combines their text representations, separating them with a comma, while 36 skipping any empty representations. The output will never contain a dangling 37 leading comma, double comma, or leading trailing comma, unless they were 38 explicitly generated by the inner encoders. Compare `SliceCommaAppender` 39 which takes an arbitrary slice. 40 */ 41 type CommaAppender[A AppenderTo] []A 42 43 // Implement `fmt.Stringer` by calling `.AppendTo`. 44 func (self CommaAppender[_]) String() string { return AppenderString(&self) } 45 46 /* 47 Implement `AppenderTo`. Appends comma-separated text representations of the inner 48 encoders to the output buffer, skipping any empty representations. 49 */ 50 func (self CommaAppender[_]) AppendTo(buf []byte) []byte { 51 var found bool 52 53 for _, val := range self { 54 if (found && TryAppendWith(&buf, `,`, val)) || TryAppendWith(&buf, ``, val) { 55 found = true 56 } 57 } 58 59 return buf 60 } 61 62 /* 63 Intermediary tool for implementing SQL array encoding. The inner value must be 64 either nil, a slice/array, or a pointer to a slice/array, where each element 65 must implement `AppenderTo`. When `.AppendTo` or `.String` is called, this combines 66 the text representations of the elements, separating them with a comma, while 67 skipping any empty representations. The output will never contain a dangling 68 leading comma, double comma, or leading trailing comma, unless they were 69 explicitly generated by the inner encoders. Compare `CommaAppender` which 70 itself is a slice. 71 */ 72 type SliceCommaAppender [1]any 73 74 // Implement `fmt.Stringer` by calling `.AppendTo`. 75 func (self SliceCommaAppender) String() string { return AppenderString(&self) } 76 77 /* 78 Implement `AppenderTo`. Appends comma-separated text representations of the inner 79 encoders to the output buffer, skipping any empty representations. 80 */ 81 func (self SliceCommaAppender) AppendTo(buf []byte) []byte { 82 if self[0] == nil { 83 return buf 84 } 85 86 val, _ := self[0].(AppenderTo) 87 if val != nil { 88 return val.AppendTo(buf) 89 } 90 91 src := valueOf(self[0]) 92 if !src.IsValid() { 93 return buf 94 } 95 96 var found bool 97 for ind := range counter(src.Len()) { 98 elem := src.Index(ind) 99 if !elem.IsValid() { 100 continue 101 } 102 103 iface := elem.Interface() 104 if iface == nil { 105 continue 106 } 107 108 val := iface.(AppenderTo) 109 if (found && TryAppendWith(&buf, `,`, val)) || TryAppendWith(&buf, ``, val) { 110 found = true 111 } 112 } 113 114 return buf 115 }