Add lasterror on statement to return errors when chain operations (#1151)

* add lasterror on statement to return errors when chain operations

* add tests for last error

* refactor error
This commit is contained in:
Lunny Xiao 2019-01-20 11:45:42 +08:00 committed by GitHub
parent 58b4f7f109
commit c68531db53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 49 additions and 3 deletions

View File

@ -26,6 +26,8 @@ var (
ErrNotImplemented = errors.New("Not implemented") ErrNotImplemented = errors.New("Not implemented")
// ErrConditionType condition type unsupported // ErrConditionType condition type unsupported
ErrConditionType = errors.New("Unsupported condition type") ErrConditionType = errors.New("Unsupported condition type")
// ErrUnSupportedSQLType parameter of SQL is not supported
ErrUnSupportedSQLType = errors.New("unsupported sql type")
) )
// ErrFieldIsNotExist columns does not exist // ErrFieldIsNotExist columns does not exist

View File

@ -79,6 +79,10 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
defer session.Close() defer session.Close()
} }
if session.statement.lastError != nil {
return 0, session.statement.lastError
}
if err := session.statement.setRefBean(bean); err != nil { if err := session.statement.setRefBean(bean); err != nil {
return 0, err return 0, err
} }

View File

@ -19,6 +19,10 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
defer session.Close() defer session.Close()
} }
if session.statement.lastError != nil {
return false, session.statement.lastError
}
var sqlStr string var sqlStr string
var args []interface{} var args []interface{}
var err error var err error

View File

@ -63,6 +63,10 @@ func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...inte
} }
func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error { func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
if session.statement.lastError != nil {
return session.statement.lastError
}
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr)) sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map { if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map {
return errors.New("needs a pointer to a slice or a map") return errors.New("needs a pointer to a slice or a map")

View File

@ -24,6 +24,10 @@ func (session *Session) Get(bean interface{}) (bool, error) {
} }
func (session *Session) get(bean interface{}) (bool, error) { func (session *Session) get(bean interface{}) (bool, error) {
if session.statement.lastError != nil {
return false, session.statement.lastError
}
beanValue := reflect.ValueOf(bean) beanValue := reflect.ValueOf(bean)
if beanValue.Kind() != reflect.Ptr { if beanValue.Kind() != reflect.Ptr {
return false, errors.New("needs a pointer to a value") return false, errors.New("needs a pointer to a value")

View File

@ -23,6 +23,10 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
defer session.Close() defer session.Close()
} }
if session.statement.lastError != nil {
return session.statement.lastError
}
if session.statement.bufferSize > 0 { if session.statement.bufferSize > 0 {
return session.bufferIterate(bean, fun) return session.bufferIterate(bean, fun)
} }

View File

@ -147,6 +147,10 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
defer session.Close() defer session.Close()
} }
if session.statement.lastError != nil {
return 0, session.statement.lastError
}
v := rValue(bean) v := rValue(bean)
t := v.Type() t := v.Type()

View File

@ -1331,3 +1331,21 @@ func TestUpdateCondiBean(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
} }
func TestWhereCondErrorWhenUpdate(t *testing.T) {
type AuthRequestError struct {
ChallengeToken string
RequestToken string
}
assert.NoError(t, prepareEngine())
assertSync(t, new(AuthRequestError))
_, err := testEngine.Cols("challenge_token", "request_token", "challenge_agent", "status").
Where(&AuthRequestError{ChallengeToken: "1"}).
Update(&AuthRequestError{
ChallengeToken: "2",
})
assert.Error(t, err)
assert.EqualValues(t, ErrConditionType, err)
}

View File

@ -60,6 +60,7 @@ type Statement struct {
cond builder.Cond cond builder.Cond
bufferSize int bufferSize int
context ContextCache context ContextCache
lastError error
} }
// Init reset all the statement's fields // Init reset all the statement's fields
@ -101,6 +102,7 @@ func (statement *Statement) Init() {
statement.cond = builder.NewCond() statement.cond = builder.NewCond()
statement.bufferSize = 0 statement.bufferSize = 0
statement.context = nil statement.context = nil
statement.lastError = nil
} }
// NoAutoCondition if you do not want convert bean's field as query condition, then use this function // NoAutoCondition if you do not want convert bean's field as query condition, then use this function
@ -125,13 +127,13 @@ func (statement *Statement) SQL(query interface{}, args ...interface{}) *Stateme
var err error var err error
statement.RawSQL, statement.RawParams, err = query.(*builder.Builder).ToSQL() statement.RawSQL, statement.RawParams, err = query.(*builder.Builder).ToSQL()
if err != nil { if err != nil {
statement.Engine.logger.Error(err) statement.lastError = err
} }
case string: case string:
statement.RawSQL = query.(string) statement.RawSQL = query.(string)
statement.RawParams = args statement.RawParams = args
default: default:
statement.Engine.logger.Error("unsupported sql type") statement.lastError = ErrUnSupportedSQLType
} }
return statement return statement
@ -160,7 +162,7 @@ func (statement *Statement) And(query interface{}, args ...interface{}) *Stateme
} }
} }
default: default:
// TODO: not support condition type statement.lastError = ErrConditionType
} }
return statement return statement