Skip to content

Commit

Permalink
prevent empty query to be executed
Browse files Browse the repository at this point in the history
  • Loading branch information
sio4 committed Sep 25, 2022
1 parent d71c504 commit 9efb85f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
10 changes: 10 additions & 0 deletions executors.go
Expand Up @@ -20,10 +20,16 @@ func (c *Connection) Reload(model interface{}) error {
})
}

// TODO: consider merging the following two methods.

// Exec runs the given query.
func (q *Query) Exec() error {
return q.Connection.timeFunc("Exec", func() error {
sql, args := q.ToSQL(nil)
if sql == "" {
return fmt.Errorf("empty query")
}

log(logging.SQL, sql, args...)
_, err := q.Connection.Store.Exec(sql, args...)
return err
Expand All @@ -36,6 +42,10 @@ func (q *Query) ExecWithCount() (int, error) {
count := int64(0)
return int(count), q.Connection.timeFunc("Exec", func() error {
sql, args := q.ToSQL(nil)
if sql == "" {
return fmt.Errorf("empty query")
}

log(logging.SQL, sql, args...)
result, err := q.Connection.Store.Exec(sql, args...)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions query.go
Expand Up @@ -213,6 +213,10 @@ func Q(c *Connection) *Query {
// from the `Model` passed in.
func (q Query) ToSQL(model *Model, addColumns ...string) (string, []interface{}) {
sb := q.toSQLBuilder(model, addColumns...)
// nil model is allowed only when if RawSQL is provided.
if model == nil && (q.RawSQL == nil || q.RawSQL.Fragment == "") {
return "", nil
}
return sb.String(), sb.Args()
}

Expand Down
19 changes: 19 additions & 0 deletions query_test.go
Expand Up @@ -386,3 +386,22 @@ func Test_ToSQL_RawQuery(t *testing.T) {
a.Equal(args, []interface{}{"random", "query"})
})
}

func Test_RawQuery_Empty(t *testing.T) {
Debug = true
defer func() { Debug = false }()

t.Run("EmptyQuery", func(t *testing.T) {
r := require.New(t)
transaction(func(tx *Connection) {
r.Error(tx.Q().Exec())
})
})

t.Run("EmptyRawQuery", func(t *testing.T) {
r := require.New(t)
transaction(func(tx *Connection) {
r.Error(tx.RawQuery("").Exec())
})
})
}
18 changes: 11 additions & 7 deletions sql_builder.go
Expand Up @@ -17,6 +17,8 @@ type sqlBuilder struct {
AddColumns []string
sql string
args []interface{}
isCompiled bool
err error
}

func newSQLBuilder(q Query, m *Model, addColumns ...string) *sqlBuilder {
Expand All @@ -25,6 +27,7 @@ func newSQLBuilder(q Query, m *Model, addColumns ...string) *sqlBuilder {
Model: m,
AddColumns: addColumns,
args: []interface{}{},
isCompiled: false,
}
}

Expand Down Expand Up @@ -53,19 +56,15 @@ func hasLimitOrOffset(sqlString string) bool {
}

func (sq *sqlBuilder) String() string {
if sq.sql == "" {
if !sq.isCompiled {
sq.compile()
}
return sq.sql
}

func (sq *sqlBuilder) Args() []interface{} {
if len(sq.args) == 0 {
if len(sq.Query.RawSQL.Arguments) > 0 {
sq.args = sq.Query.RawSQL.Arguments
} else {
sq.compile()
}
if !sq.isCompiled {
sq.compile()
}
return sq.args
}
Expand All @@ -83,7 +82,12 @@ func (sq *sqlBuilder) compile() {
}
sq.sql = sq.Query.RawSQL.Fragment
}
sq.args = sq.Query.RawSQL.Arguments
} else {
if sq.Model == nil {
sq.err = fmt.Errorf("sqlBuilder.compile() called but no RawSQL and Model specified")
return
}
switch sq.Query.Operation {
case Select:
sq.sql = sq.buildSelectSQL()
Expand Down

0 comments on commit 9efb85f

Please sign in to comment.