Skip to content

Commit faedda1

Browse files
committed
ErrColumnsWithoutStructFields
1 parent 56fab7e commit faedda1

File tree

12 files changed

+284
-68
lines changed

12 files changed

+284
-68
lines changed

errors.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"context"
55
"database/sql"
66
"errors"
7+
"fmt"
8+
"reflect"
79
"time"
810
)
911

@@ -59,6 +61,153 @@ const (
5961
ErrNotSupported sentinelError = "not supported"
6062
)
6163

64+
// ErrColumnsWithoutStructFields
65+
66+
type ErrColumnsWithoutStructFields struct {
67+
Columns []string
68+
Struct reflect.Value
69+
}
70+
71+
func (e ErrColumnsWithoutStructFields) Error() string {
72+
return fmt.Sprintf("columns %#v has no mapped struct field in %s", e.Columns, e.Struct.Type())
73+
}
74+
75+
// ErrStructFieldHasNoColumn
76+
77+
type ErrStructFieldHasNoColumn struct {
78+
StructField reflect.StructField
79+
Columns []string
80+
}
81+
82+
func (e ErrStructFieldHasNoColumn) Error() string {
83+
return fmt.Sprintf("struct field %s has no mapped column in %#v", e.StructField.Name, e.Columns)
84+
}
85+
86+
// ErrRaisedException
87+
88+
type ErrRaisedException struct {
89+
Message string
90+
}
91+
92+
func (e ErrRaisedException) Error() string {
93+
return "raised exception: " + e.Message
94+
}
95+
96+
// ErrIntegrityConstraintViolation
97+
98+
type ErrIntegrityConstraintViolation struct {
99+
Constraint string
100+
}
101+
102+
func (e ErrIntegrityConstraintViolation) Error() string {
103+
if e.Constraint == "" {
104+
return "integrity constraint violation"
105+
}
106+
return "integrity constraint violation of constraint: " + e.Constraint
107+
}
108+
109+
// ErrRestrictViolation
110+
111+
type ErrRestrictViolation struct {
112+
Constraint string
113+
}
114+
115+
func (e ErrRestrictViolation) Error() string {
116+
if e.Constraint == "" {
117+
return "restrict violation"
118+
}
119+
return "restrict violation of constraint: " + e.Constraint
120+
}
121+
122+
func (e ErrRestrictViolation) Unwrap() error {
123+
return ErrIntegrityConstraintViolation{Constraint: e.Constraint}
124+
}
125+
126+
// ErrNotNullViolation
127+
128+
type ErrNotNullViolation struct {
129+
Constraint string
130+
}
131+
132+
func (e ErrNotNullViolation) Error() string {
133+
if e.Constraint == "" {
134+
return "not null violation"
135+
}
136+
return "not null violation of constraint: " + e.Constraint
137+
}
138+
139+
func (e ErrNotNullViolation) Unwrap() error {
140+
return ErrIntegrityConstraintViolation{Constraint: e.Constraint}
141+
}
142+
143+
// ErrForeignKeyViolation
144+
145+
type ErrForeignKeyViolation struct {
146+
Constraint string
147+
}
148+
149+
func (e ErrForeignKeyViolation) Error() string {
150+
if e.Constraint == "" {
151+
return "foreign key violation"
152+
}
153+
return "foreign key violation of constraint: " + e.Constraint
154+
}
155+
156+
func (e ErrForeignKeyViolation) Unwrap() error {
157+
return ErrIntegrityConstraintViolation{Constraint: e.Constraint}
158+
}
159+
160+
// ErrUniqueViolation
161+
162+
type ErrUniqueViolation struct {
163+
Constraint string
164+
}
165+
166+
func (e ErrUniqueViolation) Error() string {
167+
if e.Constraint == "" {
168+
return "unique violation"
169+
}
170+
return "unique violation of constraint: " + e.Constraint
171+
}
172+
173+
func (e ErrUniqueViolation) Unwrap() error {
174+
return ErrIntegrityConstraintViolation{Constraint: e.Constraint}
175+
}
176+
177+
// ErrCheckViolation
178+
179+
type ErrCheckViolation struct {
180+
Constraint string
181+
}
182+
183+
func (e ErrCheckViolation) Error() string {
184+
if e.Constraint == "" {
185+
return "check violation"
186+
}
187+
return "check violation of constraint: " + e.Constraint
188+
}
189+
190+
func (e ErrCheckViolation) Unwrap() error {
191+
return ErrIntegrityConstraintViolation{Constraint: e.Constraint}
192+
}
193+
194+
// ErrExclusionViolation
195+
196+
type ErrExclusionViolation struct {
197+
Constraint string
198+
}
199+
200+
func (e ErrExclusionViolation) Error() string {
201+
if e.Constraint == "" {
202+
return "exclusion violation"
203+
}
204+
return "exclusion violation of constraint: " + e.Constraint
205+
}
206+
207+
func (e ErrExclusionViolation) Unwrap() error {
208+
return ErrIntegrityConstraintViolation{Constraint: e.Constraint}
209+
}
210+
62211
// ConnectionWithError
63212

64213
// ConnectionWithError returns a dummy Connection

examples/user_demo/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/domonda/go-sqldb/examples/user_demo
22

3-
go 1.19
3+
go 1.21
44

55
require (
66
github.com/domonda/go-sqldb v0.0.0-20230223092012-ed67c9f07bb0

go.mod

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
module github.com/domonda/go-sqldb
22

3-
go 1.19
3+
go 1.21
44

55
require (
6-
github.com/domonda/go-errs v0.0.0-20230207132857-bf0bda36a13a
7-
github.com/domonda/go-types v0.0.0-20230218120848-a48cfd6869c1
8-
github.com/lib/pq v1.10.7
9-
github.com/stretchr/testify v1.8.1
10-
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
6+
github.com/domonda/go-errs v0.0.0-20230810132956-1b6272f9fc8f
7+
github.com/domonda/go-types v0.0.0-20230829145420-30f9974e0bc7
8+
github.com/lib/pq v1.10.9
9+
github.com/stretchr/testify v1.8.4
1110
)
1211

1312
require (
1413
github.com/davecgh/go-spew v1.1.1 // indirect
15-
github.com/domonda/go-pretty v0.0.0-20220317123925-dd9e6bef129a // indirect
14+
github.com/domonda/go-pretty v0.0.0-20230810130018-8920f571470a // indirect
1615
github.com/jinzhu/now v1.1.5 // indirect
1716
github.com/kr/pretty v0.1.0 // indirect
1817
github.com/pmezard/go-difflib v1.0.0 // indirect
19-
github.com/ungerik/go-reflection v0.0.0-20220113085621-6c5fc1f2694a // indirect
18+
github.com/ungerik/go-reflection v0.0.0-20230810134712-a63435f6bc7e // indirect
2019
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
2120
gopkg.in/yaml.v3 v3.0.1 // indirect
2221
)

go.sum

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,28 @@
1-
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
21
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
32
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4-
github.com/domonda/go-errs v0.0.0-20230207132857-bf0bda36a13a h1:5AcAgYGu1ayZP1+V8W8+CFxCh8Si5u82Xp9mKArFNss=
5-
github.com/domonda/go-errs v0.0.0-20230207132857-bf0bda36a13a/go.mod h1:r9rjz9Xo8n4hNV3M47CY5quNOLBlNYuzBVC4Qk2JDOY=
6-
github.com/domonda/go-pretty v0.0.0-20220317123925-dd9e6bef129a h1:6/Is0KGl5Ot3E8ZLAgAFWYiSRdU+3t3jL38+5yIlCV4=
7-
github.com/domonda/go-pretty v0.0.0-20220317123925-dd9e6bef129a/go.mod h1:3QkM8UJdyJMeKZiIo7hYzSkQBpRS3k0gOHw4ysyEIB4=
8-
github.com/domonda/go-types v0.0.0-20230218120848-a48cfd6869c1 h1:vtdhc3dr8UHodWjGha2pkyRFzfEqvZ+7LK2A3XSWit4=
9-
github.com/domonda/go-types v0.0.0-20230218120848-a48cfd6869c1/go.mod h1:oZMN5kztmvCTnoaBA2BWOkcMHhp3lggOwp8Xp3V7kRs=
3+
github.com/domonda/go-errs v0.0.0-20230810132956-1b6272f9fc8f h1:OQaXlKXZc52Vsz7iH23NhddeMr0niW0tetB8Fq3k4yQ=
4+
github.com/domonda/go-errs v0.0.0-20230810132956-1b6272f9fc8f/go.mod h1:DYkFE3rxUGhTCMmR5MpQ2NTtoCPiORdjBATGkIEeGKM=
5+
github.com/domonda/go-pretty v0.0.0-20230810130018-8920f571470a h1:b3a6MwwMrHR9dw6585e3Ky51T50OKuD3fRuLyh8ziEw=
6+
github.com/domonda/go-pretty v0.0.0-20230810130018-8920f571470a/go.mod h1:3QkM8UJdyJMeKZiIo7hYzSkQBpRS3k0gOHw4ysyEIB4=
7+
github.com/domonda/go-types v0.0.0-20230829145420-30f9974e0bc7 h1:riEK9SQ1O0ADGI66P1Rz2zqB+g3qlREm/wF7DINj7RI=
8+
github.com/domonda/go-types v0.0.0-20230829145420-30f9974e0bc7/go.mod h1:qMSeU/23ZUopt+1kY0pJ27iqNRtsY1jATQklyCyLRAU=
109
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
1110
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
1211
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
1312
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
1413
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
1514
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
1615
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
17-
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
18-
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
16+
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
17+
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
1918
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
2019
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
21-
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
22-
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
23-
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
24-
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
25-
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
26-
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
27-
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
28-
github.com/ungerik/go-reflection v0.0.0-20220113085621-6c5fc1f2694a h1:9vfYtqoyrPw08TbSLxkSXEflp6iXa3RL86Qjs+DrVas=
29-
github.com/ungerik/go-reflection v0.0.0-20220113085621-6c5fc1f2694a/go.mod h1:6Hnd2/4g3Tpt6TjvxHx8wXOZziwApVxRdIGkr7vNpXs=
30-
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w=
31-
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
20+
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
21+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
22+
github.com/ungerik/go-reflection v0.0.0-20230810134712-a63435f6bc7e h1:BPksMeVdgSD8L4yXHYSY3HpdJ/5z2Ok5lF6PxHIVgEQ=
23+
github.com/ungerik/go-reflection v0.0.0-20230810134712-a63435f6bc7e/go.mod h1:1Q14POg/xa/P6/hWKfnUexqUhW1X6jgw+6gG7lOne1E=
3224
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
3325
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
3426
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
35-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
3627
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
3728
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

go.work

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
go 1.20
1+
go 1.21
22

33
use (
44
.

go.work.sum

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,40 @@
11
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI=
2+
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8=
3+
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
24
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
5+
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
36
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
7+
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
8+
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
49
github.com/jaytaylor/html2text v0.0.0-20211105163654-bc68cce691ba h1:QFQpJdgbON7I0jr2hYW7Bs+XV0qjc3d5tZoDnRFnqTg=
10+
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
511
github.com/jhillyerd/enmime v0.10.1 h1:3VP8gFhK7R948YJBrna5bOgnTXEuPAoICo79kKkBKfA=
12+
github.com/jhillyerd/enmime v1.0.0/go.mod h1:EktNOa/V6ka9yCrfoB2uxgefp1lno6OVdszW0iQ5LnM=
613
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
14+
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
715
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
16+
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
817
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
18+
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
919
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
20+
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
21+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
22+
github.com/teamwork/test v0.0.0-20200108114543-02621bae84ad/go.mod h1:TIbx7tx6WHBjQeLRM4eWQZBL7kmBZ7/KI4x4v7Y5YmA=
1023
github.com/teamwork/tnef v0.0.0-20200108124832-7deabccfdb32 h1:j15wq0XPAY/HR/0+dtwUrIrF2ZTKbk7QIES2p4dAG+k=
24+
github.com/teamwork/tnef v0.0.0-20200108124832-7deabccfdb32/go.mod h1:v7dFaQrF/4+curx7UTH9rqTkHTgXqghfI3thANW150o=
25+
github.com/teamwork/utils v0.0.0-20220314153103-637fa45fa6cc/go.mod h1:3Fn0qxFeRNpvsg/9T1+btOOOKkd1qG2nPYKKcOmNpcs=
1126
github.com/ungerik/go-fs v0.0.0-20230206141012-abb864f815e3 h1:IEm9Je1L3HAIEwiXOuGgJuUPjXXHzf/1e704VyIbcGc=
27+
github.com/ungerik/go-fs v0.0.0-20230810132455-f7ff27f6fa2b/go.mod h1:P8k1DG+Ox0KP4MFNTSPd8ojoDUwXjrWdGjsssF6vT/g=
28+
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
29+
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
30+
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
31+
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
32+
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
33+
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
34+
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
35+
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
1236
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
37+
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
38+
gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
1339
mvdan.cc/xurls/v2 v2.4.0 h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc=
40+
mvdan.cc/xurls/v2 v2.5.0/go.mod h1:yQgaGQ1rFtJUzkmKiHYSSfuQxqfYmd//X6PxvholpeE=

impl/reflectstruct.go

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import (
44
"errors"
55
"fmt"
66
"reflect"
7-
"strings"
8-
9-
"golang.org/x/exp/slices"
7+
"slices"
108

119
"github.com/domonda/go-sqldb"
1210
)
@@ -44,7 +42,20 @@ func ReflectStructValues(structVal reflect.Value, mapper sqldb.StructFieldMapper
4442
return columns, pkCols, values
4543
}
4644

45+
// ReflectStructColumnPointers uses the passed mapper
46+
// to find the passed columns as fields of the passed struct
47+
// and returns a pointer to a struct field for every mapped column.
48+
//
49+
// If columns and struct fields could not be mapped 1:1 then
50+
// an ErrColumnsWithoutStructFields or ErrStructFieldHasNoColumn
51+
// error is returned together with the successfully mapped pointers.
4752
func ReflectStructColumnPointers(structVal reflect.Value, mapper sqldb.StructFieldMapper, columns []string) (pointers []any, err error) {
53+
if structVal.Kind() != reflect.Struct {
54+
return nil, fmt.Errorf("got %s instead of a struct", structVal)
55+
}
56+
if !structVal.CanAddr() {
57+
return nil, errors.New("struct can't be addressed")
58+
}
4859
if len(columns) == 0 {
4960
return nil, errors.New("no columns")
5061
}
@@ -53,21 +64,18 @@ func ReflectStructColumnPointers(structVal reflect.Value, mapper sqldb.StructFie
5364
if err != nil {
5465
return nil, err
5566
}
56-
for _, ptr := range pointers {
57-
if ptr != nil {
58-
continue
67+
// Check if any column could not be mapped onto the struct,
68+
// indicated by having a nil struct field pointer.
69+
var nilCols sqldb.ErrColumnsWithoutStructFields
70+
for i, ptr := range pointers {
71+
if ptr == nil {
72+
nilCols.Columns = append(nilCols.Columns, columns[i])
73+
nilCols.Struct = structVal
5974
}
60-
nilCols := new(strings.Builder)
61-
for i, ptr := range pointers {
62-
if ptr != nil {
63-
continue
64-
}
65-
if nilCols.Len() > 0 {
66-
nilCols.WriteString(", ")
67-
}
68-
fmt.Fprintf(nilCols, "column=%s, index=%d", columns[i], i)
69-
}
70-
return nil, fmt.Errorf("columns have no mapped struct fields in %s: %s", structVal.Type(), nilCols)
75+
}
76+
if len(nilCols.Columns) > 0 {
77+
pointers = slices.DeleteFunc(pointers, func(e any) bool { return e == nil })
78+
return pointers, nilCols
7179
}
7280
return pointers, nil
7381
}

impl/update.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ import (
55
"database/sql/driver"
66
"fmt"
77
"reflect"
8+
"slices"
89
"strings"
910

10-
"golang.org/x/exp/slices"
11-
1211
"github.com/domonda/go-sqldb"
1312
)
1413

impl/upsert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import (
44
"context"
55
"fmt"
66
"reflect"
7+
"slices"
78
"strings"
89

910
sqldb "github.com/domonda/go-sqldb"
10-
"golang.org/x/exp/slices"
1111
)
1212

1313
// UpsertStruct upserts a row to table using the exported fields

mysqlconn/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/domonda/go-sqldb/mysqlconn
22

3-
go 1.20
3+
go 1.21
44

55
require (
66
github.com/domonda/go-sqldb v0.0.0-20230306182246-f05b99238fd7 // indirect

0 commit comments

Comments
 (0)