Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2ac5329

Browse files
authored
feat(coderd/database): generate foreign key constraints and add database.IsForeignKeyViolation (#9657)
* feat(coderd/database): generate foreign key constraints, add database.IsForeignKeyViolation* address PR comments
1 parenta6f7f71 commit2ac5329

File tree

5 files changed

+160
-4
lines changed

5 files changed

+160
-4
lines changed

‎coderd/apikey.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
9191
TokenName:tokenName,
9292
})
9393
iferr!=nil {
94-
ifdatabase.IsUniqueViolation(err,database.UniqueIndexApiKeyName) {
94+
ifdatabase.IsUniqueViolation(err,database.UniqueIndexAPIKeyName) {
9595
httpapi.Write(ctx,rw,http.StatusConflict, codersdk.Response{
9696
Message:fmt.Sprintf("A token with name %q already exists.",tokenName),
9797
Validations: []codersdk.ValidationError{{

‎coderd/database/errors.go‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,28 @@ func IsUniqueViolation(err error, uniqueConstraints ...UniqueConstraint) bool {
3737
returnfalse
3838
}
3939

40+
// IsForeignKeyViolation checks if the error is due to a foreign key violation.
41+
// If one or more specific foreign key constraints are given as arguments,
42+
// the error must be caused by one of them. If no constraints are given,
43+
// this function returns true for any foreign key violation.
44+
funcIsForeignKeyViolation(errerror,foreignKeyConstraints...ForeignKeyConstraint)bool {
45+
varpqErr*pq.Error
46+
iferrors.As(err,&pqErr) {
47+
ifpqErr.Code.Name()=="foreign_key_violation" {
48+
iflen(foreignKeyConstraints)==0 {
49+
returntrue
50+
}
51+
for_,fc:=rangeforeignKeyConstraints {
52+
ifpqErr.Constraint==string(fc) {
53+
returntrue
54+
}
55+
}
56+
}
57+
}
58+
59+
returnfalse
60+
}
61+
4062
// IsQueryCanceledError checks if the error is due to a query being canceled.
4163
funcIsQueryCanceledError(errerror)bool {
4264
varpqErr*pq.Error

‎coderd/database/foreign_key_constraint.go‎

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/unique_constraint.go‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎scripts/dbgen/main.go‎

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ return %s
8484
returnxerrors.Errorf("generate unique constraints: %w",err)
8585
}
8686

87+
err=generateForeignKeyConstraints()
88+
iferr!=nil {
89+
returnxerrors.Errorf("generate foreign key constraints: %w",err)
90+
}
91+
8792
returnnil
8893
}
8994

@@ -125,7 +130,7 @@ func generateUniqueConstraints() error {
125130

126131
s:=&bytes.Buffer{}
127132

128-
_,_=fmt.Fprint(s,`// Code generated bygen/enum. DO NOT EDIT.
133+
_,_=fmt.Fprint(s,`// Code generated byscripts/dbgen/main.go. DO NOT EDIT.
129134
package database
130135
`)
131136
_,_=fmt.Fprint(s,`
@@ -160,6 +165,78 @@ const (
160165
returnos.WriteFile(outputPath,data,0o600)
161166
}
162167

168+
// generateForeignKeyConstraints generates the ForeignKeyConstraint enum.
169+
funcgenerateForeignKeyConstraints()error {
170+
localPath,err:=localFilePath()
171+
iferr!=nil {
172+
returnerr
173+
}
174+
databasePath:=filepath.Join(localPath,"..","..","..","coderd","database")
175+
176+
dump,err:=os.Open(filepath.Join(databasePath,"dump.sql"))
177+
iferr!=nil {
178+
returnerr
179+
}
180+
deferdump.Close()
181+
182+
varforeignKeyConstraints []string
183+
dumpScanner:=bufio.NewScanner(dump)
184+
query:=""
185+
fordumpScanner.Scan() {
186+
line:=strings.TrimSpace(dumpScanner.Text())
187+
switch {
188+
casestrings.HasPrefix(line,"--"):
189+
caseline=="":
190+
casestrings.HasSuffix(line,";"):
191+
query+=line
192+
ifstrings.Contains(query,"FOREIGN KEY") {
193+
foreignKeyConstraints=append(foreignKeyConstraints,query)
194+
}
195+
query=""
196+
default:
197+
query+=line+" "
198+
}
199+
}
200+
201+
iferr:=dumpScanner.Err();err!=nil {
202+
returnerr
203+
}
204+
205+
s:=&bytes.Buffer{}
206+
207+
_,_=fmt.Fprint(s,`// Code generated by scripts/dbgen/main.go. DO NOT EDIT.
208+
package database
209+
`)
210+
_,_=fmt.Fprint(s,`
211+
// ForeignKeyConstraint represents a named foreign key constraint on a table.
212+
type ForeignKeyConstraint string
213+
214+
// ForeignKeyConstraint enums.
215+
const (
216+
`)
217+
for_,query:=rangeforeignKeyConstraints {
218+
name:=""
219+
switch {
220+
casestrings.Contains(query,"ALTER TABLE")&&strings.Contains(query,"ADD CONSTRAINT"):
221+
name=strings.Split(query," ")[6]
222+
default:
223+
returnxerrors.Errorf("unknown foreign key constraint format: %s",query)
224+
}
225+
_,_=fmt.Fprintf(s,"\tForeignKey%s ForeignKeyConstraint = %q // %s\n",nameFromSnakeCase(name),name,query)
226+
}
227+
_,_=fmt.Fprint(s,")\n")
228+
229+
outputPath:=filepath.Join(databasePath,"foreign_key_constraint.go")
230+
231+
data,err:=imports.Process(outputPath,s.Bytes(),&imports.Options{
232+
Comments:true,
233+
})
234+
iferr!=nil {
235+
returnerr
236+
}
237+
returnos.WriteFile(outputPath,data,0o600)
238+
}
239+
163240
typestubParamsstruct {
164241
FuncNamestring
165242
Parametersstring
@@ -560,6 +637,14 @@ func nameFromSnakeCase(s string) string {
560637
ret+="JWT"
561638
case"idx":
562639
ret+="Index"
640+
case"api":
641+
ret+="API"
642+
case"uuid":
643+
ret+="UUID"
644+
case"gitsshkeys":
645+
ret+="GitSSHKeys"
646+
case"fkey":
647+
// ignore
563648
default:
564649
ret+=strings.Title(ss)
565650
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp