From cd1f61fb874b1ac7ee5083a11e6ff4ea96eec85e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Dulai?= Date: Fri, 5 Jun 2026 17:19:11 +0200 Subject: [PATCH] WIP: OrderBy implementation --- exec/select.go | 9 ++--- schema/table.go | 26 ++++++++++++++ test/select_test.go | 86 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 98 insertions(+), 23 deletions(-) diff --git a/exec/select.go b/exec/select.go index d36f979..d4dc374 100644 --- a/exec/select.go +++ b/exec/select.go @@ -98,10 +98,11 @@ func (s *Select[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { } if len(s.ordering) > 0 { - dml += " ORDER BY" - for _, orderBy := range s.ordering { - - dml += " " + orderBy.Field + " " + orderBy.Direction + orderBy, err := s.target.GetOrderByDML(s.ordering...) + if err != nil { + log.LogError("Failed to create ORDER BY part: %s", err) + } else { + dml += orderBy } } diff --git a/schema/table.go b/schema/table.go index ad4a539..4534155 100644 --- a/schema/table.go +++ b/schema/table.go @@ -1,6 +1,7 @@ package schema import ( + "errors" "reflect" "strings" @@ -218,6 +219,31 @@ func (t Table) GetDeleteDML(count int) (string, error) { return dml.String(), nil } +func (t Table) GetOrderByDML(ordering ...OrderBy) (string, error) { + var dml strings.Builder + dml.WriteString(" ORDER BY") + for _, orderBy := range ordering { + col, err := t.getColumnByField(orderBy.Field) + if err != nil { + return "", err + } + dml.WriteString(" ") + dml.WriteString(col.Name) + dml.WriteString(" ") + dml.WriteString(orderBy.Direction) + } + return dml.String(), nil +} + +func (t Table) getColumnByField(fieldName string) (Column, error) { + for _, col := range t.columns { + if col.FieldName == fieldName { + return col, nil + } + } + return Column{}, errors.New("No column for field " + fieldName + " in table " + t.name) +} + func (t Table) IsPkAuto() bool { for _, constr := range t.constraints { if constr.Type != "pk" { diff --git a/test/select_test.go b/test/select_test.go index 922b743..858bcac 100644 --- a/test/select_test.go +++ b/test/select_test.go @@ -4,6 +4,7 @@ import ( "strconv" "testing" + simpleorm "git.gdulai.com/gdulai/simpleorm" "git.gdulai.com/gdulai/simpleorm/exec" "git.gdulai.com/gdulai/simpleorm/schema" log "gitlab.com/gdulai/simpleloglvl" @@ -277,35 +278,22 @@ func TestSelectWithLimitAndOffset(t *testing.T) { } } -func TestSelectOrderBy(t *testing.T) { +func TestSelectOrderByDesc(t *testing.T) { // GIVEN orm, conn := testSetup() defer cleanUp("test.db", conn) - testA := Test{Int64Field: -1, IntField: 1, StringField: "A"} - testB := Test{Int64Field: -1, IntField: 1, StringField: "B"} - testC := Test{Int64Field: -1, IntField: 1, StringField: "C"} - testD := Test{Int64Field: -1, IntField: 1, StringField: "D"} - testE := Test{Int64Field: -1, IntField: 1, StringField: "E"} - - insertExec, err := exec.NewInsert[Test](orm, testA, testB, testC, testD, testE) + err := orderBySetup(conn, orm) if err != nil { - log.LogError("TestSelectOrderBy setup failed: %s", err) + log.LogError("TestSelectOrderByAsc setup failed: %s", err) t.Fail() return } - err = insertExec.Execute(conn) - if err != nil { - log.LogError("TestSelectOrderBy setup failed: %s", err) - t.Fail() - return - } // WHEN - selectExec, err := exec.CreateSelect[Test](orm) if err != nil { - log.LogError("TestSelectOrderBy failed: %s", err) + log.LogError("TestSelectOrderByDesc failed: %s", err) t.Fail() return } @@ -313,7 +301,47 @@ func TestSelectOrderBy(t *testing.T) { err = selectExec.Execute(conn) if err != nil { - log.LogError("TestSelectOrderBy failed: %s", err) + log.LogError("TestSelectOrderByDesc failed: %s", err) + t.Fail() + return + } + + // THEN + var resultStr string + for _, obj := range selectExec.Results() { + resultStr += obj.StringField + } + + if resultStr != "EDCBA" { + log.LogError("TestSelectOrderByDesc failed, epxected: EDCBA actual: %s", resultStr) + t.Fail() + } +} + +func TestSelectOrderByAsc(t *testing.T) { + // GIVEN + orm, conn := testSetup() + defer cleanUp("test.db", conn) + + err := orderBySetup(conn, orm) + if err != nil { + log.LogError("TestSelectOrderByAsc setup failed: %s", err) + t.Fail() + return + } + + // WHEN + selectExec, err := exec.CreateSelect[Test](orm) + if err != nil { + log.LogError("TestSelectOrderByAsc failed: %s", err) + t.Fail() + return + } + selectExec.OrderBy(schema.OrderBy{Field: "StringField", Direction: "ASC"}) + + err = selectExec.Execute(conn) + if err != nil { + log.LogError("TestSelectOrderByAsc failed: %s", err) t.Fail() return } @@ -325,7 +353,27 @@ func TestSelectOrderBy(t *testing.T) { } if resultStr != "ABCDE" { - log.LogError("TestSelectOrderBy failed, epxected: ABCDE actual: %s", resultStr) + log.LogError("TestSelectOrderByAsc failed, epxected: ABCDE actual: %s", resultStr) t.Fail() } } + +func orderBySetup(conn *simpleorm.DBConnection, orm *simpleorm.ORM) error { + insertExec, err := exec.NewInsert[Test](orm, + Test{Int64Field: -1, IntField: 1, StringField: "C"}, + Test{Int64Field: -1, IntField: 1, StringField: "D"}, + Test{Int64Field: -1, IntField: 1, StringField: "E"}, + Test{Int64Field: -1, IntField: 1, StringField: "A"}, + Test{Int64Field: -1, IntField: 1, StringField: "B"}, + ) + if err != nil { + return err + } + + err = insertExec.Execute(conn) + if err != nil { + return err + } + + return nil +}