Skip to content

Commit

Permalink
feat: [#614] Optimize facades.Orm().Query().Exists(), Order() and Cou…
Browse files Browse the repository at this point in the history
…nt() methods (#929)

* feat: [#614] Optimize facades.Orm().Query().Exists() method

* optimize Count

* optimize OrderBy

* fix test
  • Loading branch information
hwbrzzl authored Mar 3, 2025
1 parent 62ae533 commit c3e937f
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 71 deletions.
7 changes: 5 additions & 2 deletions contracts/database/orm/orm.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Query interface {
// Commit commits the changes in a transaction.
Commit() error
// Count retrieve the "count" result of the query.
Count(count *int64) error
Count() (int64, error)
// Create inserts new record into the database.
Create(value any) error
// Cursor returns a cursor, use scan to iterate over the returned rows.
Expand All @@ -61,7 +61,7 @@ type Query interface {
// Exec executes raw sql
Exec(sql string, values ...any) (*db.Result, error)
// Exists returns true if matching records exist; otherwise, it returns false.
Exists(exists *bool) error
Exists() (bool, error)
// Find finds records that match given conditions.
Find(dest any, conds ...any) error
// FindOrFail finds records that match given conditions or throws an error.
Expand Down Expand Up @@ -108,11 +108,14 @@ type Query interface {
// Omit specifies columns that should be omitted from the query.
Omit(columns ...string) Query
// Order specifies the order in which the results should be returned.
// DEPRECATED Use OrderByRaw instead.
Order(value any) Query
// OrderBy specifies the order should be ascending.
OrderBy(column string, direction ...string) Query
// OrderByDesc specifies the order should be descending.
OrderByDesc(column string) Query
// OrderByRaw specifies the order should be raw.
OrderByRaw(raw string) Query
// OrWhere add an "or where" clause to the query.
OrWhere(query any, args ...any) Query
// OrWhereBetween adds an "or where column between x and y" clause to the query.
Expand Down
6 changes: 3 additions & 3 deletions database/console/show_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,12 @@ func (r *ShowCommand) display(ctx console.Context, info databaseInfo) {
ctx.TwoColumnDetail("<fg=green;op=bold>Views</>", "<fg=yellow;op=bold>Rows</>")
for i := range info.Views {
if !str.Of(info.Views[i].Name).StartsWith("pg_catalog", "information_schema", "spt_") {
var rows int64
if err := r.schema.Orm().Query().Table(info.Views[i].Name).Count(&rows); err != nil {
count, err := r.schema.Orm().Query().Table(info.Views[i].Name).Count()
if err != nil {
ctx.Error(err.Error())
return
}
ctx.TwoColumnDetail(info.Views[i].Name, fmt.Sprintf("%d", rows))
ctx.TwoColumnDetail(info.Views[i].Name, fmt.Sprintf("%d", count))
}
}
ctx.NewLine()
Expand Down
3 changes: 1 addition & 2 deletions database/console/show_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ func TestShowCommand(t *testing.T) {
mockOrm.EXPECT().Query().Return(mockQuery).Once()
mockQuery.EXPECT().Table("test").Return(mockQuery).Once()

var rows int64
mockQuery.EXPECT().Count(&rows).Return(nil).Once()
mockQuery.EXPECT().Count().Return(int64(0), nil).Once()
mockContext.EXPECT().NewLine().Times(4)
for i := range successCaseExpected {
mockContext.EXPECT().TwoColumnDetail(successCaseExpected[i][0], successCaseExpected[i][1]).Once()
Expand Down
43 changes: 34 additions & 9 deletions database/gorm/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,17 @@ func (r *Query) Commit() error {
return r.instance.Commit().Error
}

func (r *Query) Count(count *int64) error {
func (r *Query) Count() (int64, error) {
query := r.buildConditions()

return query.instance.Count(count).Error
var count int64

err := query.instance.Count(&count).Error
if err != nil {
return 0, err
}

return count, nil
}

func (r *Query) Create(value any) error {
Expand Down Expand Up @@ -220,10 +227,16 @@ func (r *Query) Exec(sql string, values ...any) (*contractsdb.Result, error) {
}, result.Error
}

func (r *Query) Exists(exists *bool) error {
func (r *Query) Exists() (bool, error) {
query := r.buildConditions()

return query.instance.Select("1").Limit(1).Find(exists).Error
var exists bool
err := query.instance.Select("1").Limit(1).Find(&exists).Error
if err != nil {
return false, err
}

return exists, nil
}

func (r *Query) Find(dest any, conds ...any) error {
Expand Down Expand Up @@ -556,6 +569,7 @@ func (r *Query) Omit(columns ...string) contractsorm.Query {
return r.setConditions(conditions)
}

// DEPRECATED: Use OrderByRaw instead
func (r *Query) Order(value any) contractsorm.Query {
conditions := r.conditions
conditions.order = append(r.conditions.order, value)
Expand All @@ -570,19 +584,26 @@ func (r *Query) OrderBy(column string, direction ...string) contractsorm.Query {
} else {
orderDirection = "ASC"
}
return r.Order(fmt.Sprintf("%s %s", column, orderDirection))
return r.OrderByRaw(fmt.Sprintf("%s %s", column, orderDirection))
}

func (r *Query) OrderByDesc(column string) contractsorm.Query {
return r.Order(fmt.Sprintf("%s DESC", column))
return r.OrderByRaw(fmt.Sprintf("%s DESC", column))
}

func (r *Query) OrderByRaw(raw string) contractsorm.Query {
conditions := r.conditions
conditions.order = append(r.conditions.order, raw)

return r.setConditions(conditions)
}

func (r *Query) Instance() *gormio.DB {
return r.instance
}

func (r *Query) InRandomOrder() contractsorm.Query {
return r.Order(r.gormQuery.RandomOrder())
return r.OrderByRaw(r.gormQuery.RandomOrder())
}

func (r *Query) InTransaction() bool {
Expand Down Expand Up @@ -613,13 +634,17 @@ func (r *Query) Paginate(page, limit int, dest any, total *int64) error {
offset := (page - 1) * limit
if total != nil {
if query.conditions.table == nil && query.conditions.model == nil {
if err := query.Model(dest).Count(total); err != nil {
count, err := query.Model(dest).Count()
if err != nil {
return err
}
*total = count
} else {
if err := query.Count(total); err != nil {
count, err := query.Count()
if err != nil {
return err
}
*total = count
}
}

Expand Down
130 changes: 98 additions & 32 deletions mocks/database/orm/Query.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c3e937f

Please sign in to comment.