From e9ce1bde873768847ad298f8db8b14d8a61675c6 Mon Sep 17 00:00:00 2001 From: John Guo Date: Thu, 21 Nov 2024 15:08:29 +0800 Subject: [PATCH] fix(database/gdb): incompatitable statement like `Order("id", "dasc")` (#3949) --- .../drivers/mysql/mysql_z_unit_issue_test.go | 32 ++++++++++++++++ .../drivers/mysql/mysql_z_unit_model_test.go | 2 +- .../sqlite/sqlite_z_unit_model_test.go | 2 +- .../sqlitecgo/sqlitecgo_z_unit_model_test.go | 2 +- database/gdb/gdb_model_order_group.go | 37 ++++++++++++++----- 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/contrib/drivers/mysql/mysql_z_unit_issue_test.go b/contrib/drivers/mysql/mysql_z_unit_issue_test.go index 6df225fa9..b3329a8fd 100644 --- a/contrib/drivers/mysql/mysql_z_unit_issue_test.go +++ b/contrib/drivers/mysql/mysql_z_unit_issue_test.go @@ -1345,3 +1345,35 @@ func Test_Issue3626(t *testing.T) { t.Assert(count, 1) }) } + +// https://github.com/gogf/gf/issues/3932 +func Test_Issue3932(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + one, err := db.Model(table).Order("id", "desc").One() + t.AssertNil(err) + t.Assert(one["id"], 10) + }) + gtest.C(t, func(t *gtest.T) { + one, err := db.Model(table).Order("id desc").One() + t.AssertNil(err) + t.Assert(one["id"], 10) + }) + gtest.C(t, func(t *gtest.T) { + one, err := db.Model(table).Order("id desc, nickname asc").One() + t.AssertNil(err) + t.Assert(one["id"], 10) + }) + gtest.C(t, func(t *gtest.T) { + one, err := db.Model(table).Order("id desc", "nickname asc").One() + t.AssertNil(err) + t.Assert(one["id"], 10) + }) + gtest.C(t, func(t *gtest.T) { + one, err := db.Model(table).Order("id desc").Order("nickname asc").One() + t.AssertNil(err) + t.Assert(one["id"], 10) + }) +} diff --git a/contrib/drivers/mysql/mysql_z_unit_model_test.go b/contrib/drivers/mysql/mysql_z_unit_model_test.go index 6cc4237be..5f3033b36 100644 --- a/contrib/drivers/mysql/mysql_z_unit_model_test.go +++ b/contrib/drivers/mysql/mysql_z_unit_model_test.go @@ -1293,7 +1293,7 @@ func Test_Model_OrderBy(t *testing.T) { }) gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Order("NULL").All() + result, err := db.Model(table).Order(gdb.Raw("NULL")).All() t.AssertNil(err) t.Assert(len(result), TableSize) t.Assert(result[0]["nickname"].String(), "name_1") diff --git a/contrib/drivers/sqlite/sqlite_z_unit_model_test.go b/contrib/drivers/sqlite/sqlite_z_unit_model_test.go index 99fde7722..19e97bfa5 100644 --- a/contrib/drivers/sqlite/sqlite_z_unit_model_test.go +++ b/contrib/drivers/sqlite/sqlite_z_unit_model_test.go @@ -1431,7 +1431,7 @@ func Test_Model_OrderBy(t *testing.T) { }) gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Order("NULL").All() + result, err := db.Model(table).Order(gdb.Raw("NULL")).All() t.AssertNil(err) t.Assert(len(result), TableSize) t.Assert(result[0]["nickname"].String(), "name_1") diff --git a/contrib/drivers/sqlitecgo/sqlitecgo_z_unit_model_test.go b/contrib/drivers/sqlitecgo/sqlitecgo_z_unit_model_test.go index b028294d9..613ef9c64 100644 --- a/contrib/drivers/sqlitecgo/sqlitecgo_z_unit_model_test.go +++ b/contrib/drivers/sqlitecgo/sqlitecgo_z_unit_model_test.go @@ -1390,7 +1390,7 @@ func Test_Model_OrderBy(t *testing.T) { }) gtest.C(t, func(t *gtest.T) { - result, err := db.Model(table).Order("NULL").All() + result, err := db.Model(table).Order(gdb.Raw("NULL")).All() t.AssertNil(err) t.Assert(len(result), TableSize) t.Assert(result[0]["nickname"].String(), "name_1") diff --git a/database/gdb/gdb_model_order_group.go b/database/gdb/gdb_model_order_group.go index ec69818b6..664dcf540 100644 --- a/database/gdb/gdb_model_order_group.go +++ b/database/gdb/gdb_model_order_group.go @@ -15,27 +15,42 @@ import ( // Order sets the "ORDER BY" statement for the model. // -// Eg: +// Example: // Order("id desc") +// Order("id", "desc") // Order("id desc,name asc") +// Order("id desc", "name asc") // Order("id desc").Order("name asc") // Order(gdb.Raw("field(id, 3,1,2)")). func (m *Model) Order(orderBy ...interface{}) *Model { if len(orderBy) == 0 { return m } - model := m.getModel() - if model.orderBy != "" { - model.orderBy += "," - } + var ( + core = m.db.GetCore() + model = m.getModel() + ) for _, v := range orderBy { + if model.orderBy != "" { + model.orderBy += "," + } switch v.(type) { case Raw, *Raw: model.orderBy += gconv.String(v) - return model + default: + orderByStr := gconv.String(v) + if gstr.Contains(orderByStr, " ") { + model.orderBy += core.QuoteString(orderByStr) + } else { + if gstr.Equal(orderByStr, "ASC") || gstr.Equal(orderByStr, "DESC") { + model.orderBy = gstr.TrimRight(model.orderBy, ",") + model.orderBy += " " + orderByStr + } else { + model.orderBy += core.QuoteWord(orderByStr) + } + } } } - model.orderBy += model.db.GetCore().QuoteString(gstr.JoinAny(orderBy, ", ")) return model } @@ -67,10 +82,14 @@ func (m *Model) Group(groupBy ...string) *Model { if len(groupBy) == 0 { return m } - model := m.getModel() + var ( + core = m.db.GetCore() + model = m.getModel() + ) + if model.groupBy != "" { model.groupBy += "," } - model.groupBy += model.db.GetCore().QuoteString(strings.Join(groupBy, ",")) + model.groupBy += core.QuoteString(strings.Join(groupBy, ",")) return model }