add Raw Model for package gdb

This commit is contained in:
John Guo
2021-06-18 15:20:27 +08:00
parent 2606ad83ac
commit 5fba250a14
6 changed files with 51 additions and 11 deletions

View File

@ -38,6 +38,7 @@ type DB interface {
// relational databases but also for NoSQL databases in the future. The name
// "Table" is not proper for that purpose any more.
// Also see Core.Table.
// Deprecated.
Table(tableNameOrStruct ...interface{}) *Model
// Model creates and returns a new ORM model from given schema.
@ -51,6 +52,9 @@ type DB interface {
// Also see Core.Model.
Model(tableNameOrStruct ...interface{}) *Model
// Raw creates and returns a model based on a raw sql not a table.
Raw(rawSql string, args ...interface{}) *Model
// Schema creates and returns a schema.
// Also see Core.Schema.
Schema(schema string) *Schema

View File

@ -254,10 +254,7 @@ func (c *Core) doUnion(unionType int, unions ...*Model) *Model {
}
composedArgs = append(composedArgs, holderArgs...)
}
model := c.db.Model()
model.rawSql = composedSqlStr
model.extraArgs = composedArgs
return model
return c.db.Raw(composedSqlStr, composedArgs...)
}
// PingMaster pings the master node to check authentication or keeps the connection alive.

View File

@ -21,7 +21,7 @@ import (
type Model struct {
db DB // Underlying DB interface.
tx *TX // Underlying TX interface.
rawSql string // rawSql is the raw SQL string which marks a raw SQL based Model not a table based Model.
rawSql string // rawSql is the raw SQL string which marks a raw SQL based Model not a table based Model.
schema string // Custom database schema.
linkType int // Mark for operation on master or slave.
tablesInit string // Table names when model initialization.
@ -80,11 +80,14 @@ func (c *Core) Table(tableNameQueryOrStruct ...interface{}) *Model {
// Model creates and returns a new ORM model from given schema.
// The parameter `tableNameQueryOrStruct` can be more than one table names, and also alias name, like:
// 1. Model names:
// Model("user")
// Model("user u")
// Model("user, user_detail")
// Model("user u, user_detail ud")
// 2. Model name with alias: Model("user", "u")
// db.Model("user")
// db.Model("user u")
// db.Model("user, user_detail")
// db.Model("user u, user_detail ud")
// 2. Model name with alias:
// db.Model("user", "u")
// 3. Model name with sub-query:
// db.Model("? AS a, ? AS b", subQuery1, subQuery2)
func (c *Core) Model(tableNameQueryOrStruct ...interface{}) *Model {
var (
tableStr string
@ -132,6 +135,16 @@ func (c *Core) Model(tableNameQueryOrStruct ...interface{}) *Model {
}
}
// Raw creates and returns a model based on a raw sql not a table.
// Example:
// db.Raw("SELECT * FROM `user` WHERE `name` = ?", "john").Scan(&result)
func (c *Core) Raw(rawSql string, args ...interface{}) *Model {
model := c.Model()
model.rawSql = rawSql
model.extraArgs = args
return model
}
// With creates and returns an ORM model based on meta data of given object.
func (c *Core) With(objects ...interface{}) *Model {
return c.db.Model().With(objects...)

View File

@ -421,7 +421,13 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh
}
// Soft deletion.
softDeletingCondition := m.getConditionForSoftDeleting()
if !m.unscoped && softDeletingCondition != "" {
if m.rawSql != "" && conditionWhere != "" {
if gstr.ContainsI(m.rawSql, " WHERE ") {
conditionWhere = " AND " + conditionWhere
} else {
conditionWhere = " WHERE " + conditionWhere
}
} else if !m.unscoped && softDeletingCondition != "" {
if conditionWhere == "" {
conditionWhere = fmt.Sprintf(` WHERE %s`, softDeletingCondition)
} else {
@ -432,6 +438,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh
conditionWhere = " WHERE " + conditionWhere
}
}
// GROUP BY.
if m.groupBy != "" {
conditionExtra += " GROUP BY " + m.groupBy

View File

@ -3696,3 +3696,22 @@ func Test_Model_OnDuplicateEx(t *testing.T) {
t.Assert(one["nickname"], "name_1")
})
}
func Test_Model_Raw(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
all, err := db.
Raw(fmt.Sprintf("select * from %s where id in (?)", table), g.Slice{1, 5, 7, 8, 9, 10}).
WhereLT("id", 8).
WhereIn("id", g.Slice{1, 2, 3, 4, 5, 6, 7}).
OrderDesc("id").
Limit(2).
All()
t.AssertNil(err)
t.Assert(len(all), 2)
t.Assert(all[0]["id"], 7)
t.Assert(all[1]["id"], 5)
})
}