ccbhj/fix_mysql_blob_shared_bytes (#2274)
Copy the sql.RawBytes when converting to []byte. Fix issue https://gitea.com/xorm/xorm/issues/2273 Co-authored-by: Bingjia Chen <bingjia.chen@seamoney.com> Reviewed-on: https://gitea.com/xorm/xorm/pulls/2274 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: ccbhj <ccbhj@noreply.gitea.com> Co-committed-by: ccbhj <ccbhj@noreply.gitea.com>
This commit is contained in:
parent
caa8a029c6
commit
838a0d9bca
|
@ -24,7 +24,10 @@ func Interface2Interface(userLocation *time.Location, v interface{}) (interface{
|
|||
return vv.String, nil
|
||||
case *sql.RawBytes:
|
||||
if len([]byte(*vv)) > 0 {
|
||||
return []byte(*vv), nil
|
||||
src := []byte(*vv)
|
||||
dest := make([]byte, len(src))
|
||||
copy(dest, src)
|
||||
return dest, nil
|
||||
}
|
||||
return nil, nil
|
||||
case *sql.NullInt32:
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
package integrations
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"xorm.io/builder"
|
||||
|
||||
"xorm.io/xorm/schemas"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -381,3 +383,68 @@ func TestQueryStringWithLimit(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 0, len(data))
|
||||
}
|
||||
|
||||
func TestQueryBLOBInMySQL(t *testing.T) {
|
||||
assert.NoError(t, PrepareEngine())
|
||||
|
||||
var err error
|
||||
type Avatar struct {
|
||||
Id int64 `xorm:"autoincr pk"`
|
||||
Avatar []byte `xorm:"BLOB"`
|
||||
}
|
||||
|
||||
assert.NoError(t, testEngine.Sync(new(Avatar)))
|
||||
testEngine.Delete(Avatar{})
|
||||
|
||||
repeatBytes := func(n int, b byte) []byte {
|
||||
return bytes.Repeat([]byte{b}, n)
|
||||
}
|
||||
|
||||
const N = 10
|
||||
var data = []Avatar{}
|
||||
for i := 0; i < N; i++ {
|
||||
// allocate a []byte that is as twice big as the last one
|
||||
// so that the underlying buffer will need to reallocate when querying
|
||||
bs := repeatBytes(1<<(i+2), 'A'+byte(i))
|
||||
data = append(data, Avatar{
|
||||
Avatar: bs,
|
||||
})
|
||||
}
|
||||
_, err = testEngine.Insert(data)
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
testEngine.Delete(Avatar{})
|
||||
}()
|
||||
|
||||
{
|
||||
records, err := testEngine.QueryInterface("select avatar from " + testEngine.Quote(testEngine.TableName("avatar", true)))
|
||||
assert.NoError(t, err)
|
||||
for i, record := range records {
|
||||
bs := record["avatar"].([]byte)
|
||||
assert.EqualValues(t, repeatBytes(1<<(i+2), 'A'+byte(i))[:3], bs[:3])
|
||||
t.Logf("%d => %p => %02x %02x %02x", i, bs, bs[0], bs[1], bs[2])
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
arr := make([][]interface{}, 0)
|
||||
err = testEngine.Table(testEngine.Quote(testEngine.TableName("avatar", true))).Cols("avatar").Find(&arr)
|
||||
assert.NoError(t, err)
|
||||
for i, record := range arr {
|
||||
bs := record[0].([]byte)
|
||||
assert.EqualValues(t, repeatBytes(1<<(i+2), 'A'+byte(i))[:3], bs[:3])
|
||||
t.Logf("%d => %p => %02x %02x %02x", i, bs, bs[0], bs[1], bs[2])
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
arr := make([]map[string]interface{}, 0)
|
||||
err = testEngine.Table(testEngine.Quote(testEngine.TableName("avatar", true))).Cols("avatar").Find(&arr)
|
||||
assert.NoError(t, err)
|
||||
for i, record := range arr {
|
||||
bs := record["avatar"].([]byte)
|
||||
assert.EqualValues(t, repeatBytes(1<<(i+2), 'A'+byte(i))[:3], bs[:3])
|
||||
t.Logf("%d => %p => %02x %02x %02x", i, bs, bs[0], bs[1], bs[2])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue