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

Commite7e2023

Browse files
committed
Merge branch 'collect-source-db-checks' into 'master'
feat: collect and report all source databases checks at onceSee merge request postgres-ai/database-lab!798
2 parents9472180 +bf4e058 commite7e2023

File tree

2 files changed

+270
-72
lines changed
  • engine
    • internal/retrieval/engine/postgres/tools/db
    • pkg/models

2 files changed

+270
-72
lines changed

‎engine/internal/retrieval/engine/postgres/tools/db/pg.go

Lines changed: 232 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -122,55 +122,75 @@ func CheckSource(ctx context.Context, conf *models.ConnectionTest, imageContent
122122

123123
dbSource.TuningParams=tuningParameters
124124

125+
dbCheck,err:=checkDatabases(ctx,conn,conf,imageContent)
126+
iferr!=nil {
127+
dbSource.Status=models.TCStatusError
128+
dbSource.Result=models.TCResultQueryError
129+
dbSource.Message=err.Error()
130+
131+
returndbSource,err
132+
}
133+
134+
dbSource.TestConnection=dbCheck
135+
136+
returndbSource,nil
137+
}
138+
139+
funccheckDatabases(ctx context.Context,conn*pgx.Conn,conf*models.ConnectionTest,
140+
imageContent*ImageContent) (*models.TestConnection,error) {
141+
vartcResponse=&models.TestConnection{
142+
Status:models.TCStatusOK,
143+
Result:models.TCResultOK,
144+
Message:models.TCMessageOK,
145+
}
146+
125147
dbList:=conf.DBList
126148

127149
iflen(dbList)==0 {
128150
dbSourceList,err:=getDBList(ctx,conn,conf.Username)
129151
iferr!=nil {
130-
dbSource.Status=models.TCStatusError
131-
dbSource.Result=models.TCResultQueryError
132-
dbSource.Message=err.Error()
133-
134-
returndbSource,err
152+
returnnil,err
135153
}
136154

137155
dbList=dbSourceList
138156
}
139157

158+
dbReport:=make(map[string]*checkContentResp,0)
159+
140160
iflen(dbList)>maxNumberVerifiedDBs {
141161
dbList=dbList[:maxNumberVerifiedDBs]
142-
tcResponse=&models.TestConnection{
143-
Status:models.TCStatusNotice,
144-
Result:models.TCResultUnverifiedDB,
145-
Message:"Too many databases were requested to be checked. Onlythe following databases have been verified: "+
146-
strings.Join(dbList,", "),
162+
dbReport[""]=&checkContentResp{
163+
status:models.TCStatusNotice,
164+
result:models.TCResultUnverifiedDB,
165+
message:"Too many databases. Onlychecked these databases: "+
166+
strings.Join(dbList,", ")+". ",
147167
}
148-
dbSource.TestConnection=tcResponse
149168
}
150169

151170
for_,dbName:=rangedbList {
152171
dbConn,listTC:=checkConnection(ctx,conf,dbName)
153172
iflistTC!=nil {
154-
dbSource.TestConnection=listTC
155-
returndbSource,nil
173+
dbReport[dbName]=&checkContentResp{
174+
status:listTC.Status,
175+
result:listTC.Result,
176+
message:listTC.Message,
177+
}
178+
179+
continue
156180
}
157181

158-
listTC,err:=checkContent(ctx,dbConn,dbName,imageContent)
159-
iferr!=nil {
160-
dbSource.Status=models.TCStatusError
161-
dbSource.Result=models.TCResultQueryError
162-
dbSource.Message=err.Error()
182+
contentChecks:=checkDBContent(ctx,dbConn,imageContent)
163183

164-
returndbSource,err
184+
ifcontentChecks!=nil {
185+
dbReport[dbName]=contentChecks
165186
}
187+
}
166188

167-
iflistTC!=nil {
168-
dbSource.TestConnection=listTC
169-
returndbSource,nil
170-
}
189+
iflen(dbReport)>0 {
190+
tcResponse=aggregate(tcResponse,dbReport)
171191
}
172192

173-
returndbSource,nil
193+
returntcResponse,nil
174194
}
175195

176196
funcgetDBList(ctx context.Context,conn*pgx.Conn,dbUsernamestring) ([]string,error) {
@@ -193,6 +213,91 @@ func getDBList(ctx context.Context, conn *pgx.Conn, dbUsername string) ([]string
193213
returndbList,nil
194214
}
195215

216+
typeaggregateStatestruct {
217+
generalstring
218+
errorsmap[string]string
219+
missingExtmap[string][]extension
220+
unsupportedExtmap[string][]extension
221+
missingLocalesmap[string][]locale
222+
unexploredDBs []string
223+
}
224+
225+
funcnewAggregateState()aggregateState {
226+
returnaggregateState{
227+
general:"",
228+
errors:make(map[string]string,0),
229+
missingExt:make(map[string][]extension,0),
230+
unsupportedExt:make(map[string][]extension,0),
231+
missingLocales:make(map[string][]locale,0),
232+
unexploredDBs:make([]string,0),
233+
}
234+
}
235+
236+
funcaggregate(tcResponse*models.TestConnection,collectionmap[string]*checkContentResp)*models.TestConnection {
237+
agg:=newAggregateState()
238+
sb:= strings.Builder{}
239+
240+
fordbName,contentResponse:=rangecollection {
241+
ifcontentResponse.status>tcResponse.Status {
242+
tcResponse.Status=contentResponse.status
243+
tcResponse.Result=contentResponse.result
244+
}
245+
246+
switchcontentResponse.result {
247+
casemodels.TCResultUnverifiedDB:
248+
agg.general+=contentResponse.message
249+
250+
casemodels.TCResultQueryError,models.TCResultConnectionError:
251+
agg.errors[dbName]=contentResponse.message
252+
253+
casemodels.TCResultMissingExtension:
254+
iflen(contentResponse.missingExt)>0 {
255+
agg.missingExt[dbName]=append(agg.missingExt[dbName],contentResponse.missingExt...)
256+
}
257+
258+
iflen(contentResponse.unsupportedExt)>0 {
259+
agg.unsupportedExt[dbName]=append(agg.unsupportedExt[dbName],contentResponse.unsupportedExt...)
260+
}
261+
262+
casemodels.TCResultMissingLocale:
263+
agg.missingLocales[dbName]=append(agg.missingLocales[dbName],contentResponse.missingLocales...)
264+
265+
casemodels.TCResultUnexploredImage:
266+
agg.unexploredDBs=append(agg.unexploredDBs,dbName)
267+
268+
casemodels.TCResultOK:
269+
default:
270+
}
271+
}
272+
273+
sb.WriteString(agg.general)
274+
sb.WriteString(buildErrorMessage(agg.errors))
275+
sb.WriteString(buildExtensionsWarningMessage(agg.missingExt,agg.unsupportedExt))
276+
sb.WriteString(buildLocalesWarningMessage(agg.missingLocales))
277+
sb.WriteString(unexploredDBsNoticeMessage(agg.unexploredDBs))
278+
279+
tcResponse.Message=sb.String()
280+
281+
returntcResponse
282+
}
283+
284+
funcbuildErrorMessage(errorsmap[string]string)string {
285+
iflen(errors)==0 {
286+
return""
287+
}
288+
289+
sb:= strings.Builder{}
290+
sb.WriteString("Issues detected in databases:\n")
291+
292+
fordbName,message:=rangeerrors {
293+
sb.WriteString(fmt.Sprintf(" %q - %s;\n",dbName,message))
294+
}
295+
296+
sb.WriteString("\n")
297+
298+
returnsb.String()
299+
}
300+
196301
funccheckConnection(ctx context.Context,conf*models.ConnectionTest,dbNamestring) (*pgx.Conn,*models.TestConnection) {
197302
connStr:=ConnectionString(conf.Host,conf.Port,conf.Username,dbName,conf.Password)
198303

@@ -220,41 +325,59 @@ func checkConnection(ctx context.Context, conf *models.ConnectionTest, dbName st
220325
returnconn,nil
221326
}
222327

223-
funccheckContent(ctx context.Context,conn*pgx.Conn,dbNamestring,imageContent*ImageContent) (*models.TestConnection,error) {
328+
typecheckContentRespstruct {
329+
status models.StatusType
330+
resultstring
331+
messagestring
332+
missingExt []extension
333+
unsupportedExt []extension
334+
missingLocales []locale
335+
}
336+
337+
funccheckDBContent(ctx context.Context,conn*pgx.Conn,imageContent*ImageContent)*checkContentResp {
224338
if!imageContent.IsReady() {
225-
return&models.TestConnection{
226-
Status:models.TCStatusNotice,
227-
Result:models.TCResultUnexploredImage,
228-
Message:"The connectiontothedatabase was successful. "+
229-
"Details about theextensions and localesof the Docker image havenot yetbeen collected. Please try againlater",
230-
},nil
339+
return&checkContentResp{
340+
status:models.TCStatusNotice,
341+
result:models.TCResultUnexploredImage,
342+
message:"Connectedto database. "+
343+
"Docker imageextensions and locales not yetanalyzed. Retrylater.",
344+
}
231345
}
232346

233347
ifmissing,unsupported,err:=checkExtensions(ctx,conn,imageContent.Extensions());err!=nil {
234348
iferr!=errExtensionWarning {
235-
returnnil,fmt.Errorf("failed to check database extensions: %w",err)
349+
return&checkContentResp{
350+
status:models.TCStatusError,
351+
result:models.TCResultQueryError,
352+
message:fmt.Sprintf("failed to check database extensions: %s",err),
353+
}
236354
}
237355

238-
return&models.TestConnection{
239-
Status:models.TCStatusWarning,
240-
Result:models.TCResultMissingExtension,
241-
Message:buildExtensionsWarningMessage(dbName,missing,unsupported),
242-
},nil
356+
return&checkContentResp{
357+
status:models.TCStatusWarning,
358+
result:models.TCResultMissingExtension,
359+
missingExt:missing,
360+
unsupportedExt:unsupported,
361+
}
243362
}
244363

245364
ifmissing,err:=checkLocales(ctx,conn,imageContent.Locales(),imageContent.Databases());err!=nil {
246365
iferr!=errLocaleWarning {
247-
returnnil,fmt.Errorf("failed to check database locales: %w",err)
366+
return&checkContentResp{
367+
status:models.TCStatusError,
368+
result:models.TCResultQueryError,
369+
message:fmt.Sprintf("failed to check database locales: %s",err),
370+
}
248371
}
249372

250-
return&models.TestConnection{
251-
Status:models.TCStatusWarning,
252-
Result:models.TCResultMissingLocale,
253-
Message:buildLocalesWarningMessage(dbName,missing),
254-
},nil
373+
return&checkContentResp{
374+
status:models.TCStatusWarning,
375+
result:models.TCResultMissingLocale,
376+
missingLocales:missing,
377+
}
255378
}
256379

257-
returnnil,nil
380+
returnnil
258381
}
259382

260383
funccheckExtensions(ctx context.Context,conn*pgx.Conn,imageExtensionsmap[string]string) ([]extension, []extension,error) {
@@ -311,38 +434,64 @@ func toCanonicalSemver(v string) string {
311434
returnv
312435
}
313436

314-
funcbuildExtensionsWarningMessage(dbNamestring,missingExtensions,unsupportedVersions []extension)string {
437+
funcbuildExtensionsWarningMessage(missingExtensions,unsupportedVersionsmap[string][]extension)string {
315438
sb:=&strings.Builder{}
316439

317440
iflen(missingExtensions)>0 {
318-
sb.WriteString("The image specifiedinsection\"databaseContainer\"lacks the following "+
319-
"extensionsused inthesourcedatabase (\""+dbName+"\"):")
441+
sb.WriteString("Image configuredin\"databaseContainer\"missing "+
442+
"extensionsinstalled in sourcedatabases:")
320443

321444
formatExtensionList(sb,missingExtensions)
322-
323-
sb.WriteString(".\n")
324445
}
325446

326447
iflen(unsupportedVersions)>0 {
327-
sb.WriteString("The source database (\""+dbName+"\") usesextensionsthat are present "+
328-
"in imagespecified insection\"databaseContainer\" but their versions are not supported by the image:")
448+
sb.WriteString("Source databases haveextensionswith different versions "+
449+
"than imageconfigured in\"databaseContainer\":")
329450

330451
formatExtensionList(sb,unsupportedVersions)
331452
}
332453

333454
returnsb.String()
334455
}
335456

336-
funcformatExtensionList(sb*strings.Builder,extensions []extension) {
337-
length:=len(extensions)
457+
funcformatExtensionList(sb*strings.Builder,extensionMapmap[string][]extension) {
458+
varjint
459+
460+
lengthDBs:=len(extensionMap)
461+
462+
fordbName,extensions:=rangeextensionMap {
463+
lengthExt:=len(extensions)
464+
465+
sb.WriteString(" "+dbName+" (")
466+
467+
fori,missing:=rangeextensions {
468+
sb.WriteString(missing.name+" "+missing.defaultVersion)
469+
470+
ifi!=lengthExt-1 {
471+
sb.WriteString(", ")
472+
}
473+
}
338474

339-
fori,missing:=rangeextensions {
340-
sb.WriteString(" "+missing.name+" "+missing.defaultVersion)
475+
sb.WriteString(")")
341476

342-
ifi!=length-1 {
343-
sb.WriteRune(',')
477+
ifj!=lengthDBs-1 {
478+
sb.WriteRune(';')
344479
}
480+
481+
j++
345482
}
483+
484+
sb.WriteString(".\n")
485+
}
486+
487+
funcunexploredDBsNoticeMessage(dbs []string)string {
488+
iflen(dbs)==0 {
489+
return""
490+
}
491+
492+
returnfmt.Sprintf("Connected to databases: %s. "+
493+
"Docker image extensions and locales not analyzed. Retry later.\n",
494+
strings.Join(dbs,","))
346495
}
347496

348497
funccheckLocales(ctx context.Context,conn*pgx.Conn,imageLocales,databasesmap[string]struct{}) ([]locale,error) {
@@ -386,20 +535,38 @@ func checkLocales(ctx context.Context, conn *pgx.Conn, imageLocales, databases m
386535
returnnil,nil
387536
}
388537

389-
funcbuildLocalesWarningMessage(dbNamestring,missingLocales []locale)string {
538+
funcbuildLocalesWarningMessage(localeMapmap[string][]locale)string {
539+
varjint
540+
390541
sb:=&strings.Builder{}
391542

392-
iflength:=len(missingLocales);length>0 {
393-
sb.WriteString("The image specified in section\"databaseContainer\" lacks the following "+
394-
"locales used in the source database (\""+dbName+"\"):")
543+
iflengthDBs:=len(localeMap);lengthDBs>0 {
544+
sb.WriteString("Image configured in\"databaseContainer\" missing "+
545+
"locales from source databases: ")
546+
547+
fordbName,missingLocales:=rangelocaleMap {
548+
lengthLoc:=len(missingLocales)
549+
550+
sb.WriteString(" "+dbName+" (")
395551

396-
fori,missing:=rangemissingLocales {
397-
sb.WriteString(fmt.Sprintf(" '%s' (collate: %s, ctype: %s)",missing.name,missing.collate,missing.ctype))
552+
fori,missing:=rangemissingLocales {
553+
sb.WriteString(fmt.Sprintf(" '%s' (collate: %s, ctype: %s)",missing.name,missing.collate,missing.ctype))
398554

399-
ifi!=length-1 {
400-
sb.WriteRune(',')
555+
ifi!=lengthLoc-1 {
556+
sb.WriteRune(',')
557+
}
401558
}
559+
560+
sb.WriteString(")")
561+
562+
ifj!=lengthDBs-1 {
563+
sb.WriteRune(';')
564+
}
565+
566+
j++
402567
}
568+
569+
sb.WriteString(".\n")
403570
}
404571

405572
returnsb.String()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp