Skip to content
This repository has been archived by the owner on Sep 7, 2021. It is now read-only.
This repository is currently being migrated. It's locked while the migration is in progress.

Return error when find with no primary key selected #1397

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ var (
ErrConditionType = errors.New("Unsupported condition type")
// ErrUnSupportedSQLType parameter of SQL is not supported
ErrUnSupportedSQLType = errors.New("unsupported sql type")
// ErrNoPrimaryKey represents an error lack of primary key
ErrNoPrimaryKey = errors.New("Current table has no necessary primary key")
// ErrMapKeyIsNotValid represents an error map key is not valid
ErrMapKeyIsNotValid = errors.New("Map key type must be a slice because the table have serval primary keys")
)

// ErrFieldIsNotExist columns does not exist
Expand All @@ -49,3 +53,18 @@ type ErrFieldIsNotValid struct {
func (e ErrFieldIsNotValid) Error() string {
return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName)
}

// ErrPrimaryKeyNoSelected represents an error primary key not selected
type ErrPrimaryKeyNoSelected struct {
PrimaryKey string
}

func (e ErrPrimaryKeyNoSelected) Error() string {
return fmt.Sprintf("primary key %s is not selected", e.PrimaryKey)
}

// IsErrPrimaryKeyNoSelected returns true is err is ErrPrimaryKeyNoSelected
func IsErrPrimaryKeyNoSelected(err error) bool {
_, ok := err.(ErrPrimaryKeyNoSelected)
return ok
}
15 changes: 13 additions & 2 deletions session_find.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,21 @@ func (session *Session) noCacheFind(table *core.Table, containerValue reflect.Va
} else {
keyType := containerValue.Type().Key()
if len(table.PrimaryKeys) == 0 {
return errors.New("don't support multiple primary key's map has non-slice key type")
return ErrNoPrimaryKey
}
if len(table.PrimaryKeys) > 1 && keyType.Kind() != reflect.Slice {
return errors.New("don't support multiple primary key's map has non-slice key type")
return ErrMapKeyIsNotValid
}

var found bool
for _, field := range fields {
if strings.EqualFold(field, table.PrimaryKeys[0]) {
found = true
break
}
}
if !found {
return ErrPrimaryKeyNoSelected{table.PrimaryKeys[0]}
}

containerValueSetFunc = func(newValue *reflect.Value, pk core.PK) error {
Expand Down
25 changes: 24 additions & 1 deletion session_find_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"testing"
"time"

"xorm.io/core"
"github.com/stretchr/testify/assert"
"xorm.io/core"
)

func TestJoinLimit(t *testing.T) {
Expand Down Expand Up @@ -801,3 +801,26 @@ func TestFindJoin(t *testing.T) {
Where("scene_item.type=?", 3).Or("device_user_privrels.user_id=?", 339).Find(&scenes)
assert.NoError(t, err)
}

func TestFindMapCols(t *testing.T) {
type FindMapCols struct {
Id int64
ColA string
ColB string
}

assert.NoError(t, prepareEngine())
assertSync(t, new(FindMapCols))

id := testEngine.GetColumnMapper().Obj2Table("Id")
colA := testEngine.GetColumnMapper().Obj2Table("ColA")
colB := testEngine.GetColumnMapper().Obj2Table("ColB")

var objs = make(map[int64]*FindMapCols)
err := testEngine.Cols(colA, colB).Find(&objs)
assert.Error(t, err)
assert.True(t, IsErrPrimaryKeyNoSelected(err))

err = testEngine.Cols(id, colA, colB).Find(&objs)
assert.NoError(t, err)
}