From dc118b68b3ef44cbf9107a55813bebff365ff46f Mon Sep 17 00:00:00 2001 From: austin-artificial <126663376+austin-artificial@users.noreply.github.com> Date: Tue, 30 May 2023 08:46:14 +0100 Subject: [PATCH] sort the tables (#35) --- analyzer/analyzer.go | 13 +++++++++++++ analyzer/analyzer_test.go | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/analyzer/analyzer.go b/analyzer/analyzer.go index 888c8ee..e6d92c7 100644 --- a/analyzer/analyzer.go +++ b/analyzer/analyzer.go @@ -3,6 +3,7 @@ package analyzer import ( "errors" "fmt" + "sort" "github.com/sirupsen/logrus" @@ -59,6 +60,8 @@ func (a analyzer) Analyze() (*database.Result, error) { if err != nil { return nil, err } + // sort the tables so the output is more deterministic + sortTables(selectedTables) tableResults, err := a.GetColumnsAndConstraints(db, selectedTables) if err != nil { @@ -68,6 +71,16 @@ func (a analyzer) Analyze() (*database.Result, error) { return &database.Result{Tables: tableResults}, nil } +func sortTables(tables []database.TableDetail) { + sort.SliceStable(tables, func(i, j int) bool { + if tables[i].Schema != tables[j].Schema { + return tables[i].Schema < tables[j].Schema + } + return tables[i].Name < tables[j].Name + }) + +} + func (a analyzer) GetConnectionString() (string, error) { if connectionString := a.config.ConnectionString(); connectionString != "" { return connectionString, nil diff --git a/analyzer/analyzer_test.go b/analyzer/analyzer_test.go index 6d17b6f..bb5c2bf 100644 --- a/analyzer/analyzer_test.go +++ b/analyzer/analyzer_test.go @@ -257,4 +257,44 @@ func TestAnalyzer_Analyze(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, result) }) + t.Run("Sorts the tables", func(t *testing.T) { + // Arrange + analyzer, configMock, connectionFactoryMock, questionerMock := getAnalyzerWithMocks() + connectorMock := mocks.Connector{} + configMock.On("ConnectionString").Return("validConnectionString").Once() + connectionFactoryMock.On("NewConnector", "validConnectionString").Return(&connectorMock, nil).Once() + connectorMock.On("Connect").Return(nil).Once() + connectorMock.On("Close").Return().Once() + configMock.On("Schemas").Return([]string{"schemaA", "schemaB"}).Once() + // The tables returned are unsorted + configMock.On("SelectedTables").Return([]string{ + "schemaB.tableB", + "schemaA.tableB", + "schemaA.tableA", + "schemaB.tableA"}).Once() + connectorMock.On("GetColumns", database.TableDetail{Schema: "schemaA", Name: "tableA"}).Return([]database.ColumnResult{}, nil).Once() + connectorMock.On("GetColumns", database.TableDetail{Schema: "schemaA", Name: "tableB"}).Return([]database.ColumnResult{}, nil).Once() + connectorMock.On("GetColumns", database.TableDetail{Schema: "schemaB", Name: "tableA"}).Return([]database.ColumnResult{}, nil).Once() + connectorMock.On("GetColumns", database.TableDetail{Schema: "schemaB", Name: "tableB"}).Return([]database.ColumnResult{}, nil).Once() + connectorMock.On("GetConstraints", database.TableDetail{Schema: "schemaA", Name: "tableA"}).Return([]database.ConstraintResult{}, nil).Once() + connectorMock.On("GetConstraints", database.TableDetail{Schema: "schemaA", Name: "tableB"}).Return([]database.ConstraintResult{}, nil).Once() + connectorMock.On("GetConstraints", database.TableDetail{Schema: "schemaB", Name: "tableA"}).Return([]database.ConstraintResult{}, nil).Once() + connectorMock.On("GetConstraints", database.TableDetail{Schema: "schemaB", Name: "tableB"}).Return([]database.ConstraintResult{}, nil).Once() + + // Act + result, err := analyzer.Analyze() + + // Assert + configMock.AssertExpectations(t) + connectionFactoryMock.AssertExpectations(t) + questionerMock.AssertExpectations(t) + connectorMock.AssertExpectations(t) + assert.Nil(t, err) + assert.NotNil(t, result) + // The tables are now sorted + assert.Equal(t, result.Tables[0].Table, database.TableDetail{Schema: "schemaA", Name: "tableA"}) + assert.Equal(t, result.Tables[1].Table, database.TableDetail{Schema: "schemaA", Name: "tableB"}) + assert.Equal(t, result.Tables[2].Table, database.TableDetail{Schema: "schemaB", Name: "tableA"}) + assert.Equal(t, result.Tables[3].Table, database.TableDetail{Schema: "schemaB", Name: "tableB"}) + }) }