func init() { b := make([]byte, 64*1024) for ii := range b { b[ii] = byte(ii) } blob = mysql.Blob(b) writeTest = []WriteTest{ WriteTest{Bytes, append([]byte{byte(len(Bytes))}, Bytes...)}, WriteTest{String, append([]byte{byte(len(String))}, []byte(String)...)}, WriteTest{pBytes, nil}, WriteTest{pString, nil}, WriteTest{ blob, append(append([]byte{253}, EncodeU24(uint32(len(blob)))...), []byte(blob)...), }, WriteTest{ dateT, []byte{ 7, byte(dateT.Year()), byte(dateT.Year() >> 8), byte(dateT.Month()), byte(dateT.Day()), byte(dateT.Hour()), byte(dateT.Minute()), byte(dateT.Second()), }, }, WriteTest{ &dateT, []byte{ 7, byte(dateT.Year()), byte(dateT.Year() >> 8), byte(dateT.Month()), byte(dateT.Day()), byte(dateT.Hour()), byte(dateT.Minute()), byte(dateT.Second()), }, }, WriteTest{ date, []byte{ 4, byte(date.Year), byte(date.Year >> 8), byte(date.Month), byte(date.Day), }, }, WriteTest{ &date, []byte{ 4, byte(date.Year), byte(date.Year >> 8), byte(date.Month), byte(date.Day), }, }, WriteTest{ tim, []byte{12, 1, 5, 0, 0, 0, 4, 3, 2, 1, 0, 0, 0}, }, WriteTest{ &tim, []byte{12, 1, 5, 0, 0, 0, 4, 3, 2, 1, 0, 0, 0}, }, WriteTest{bol, []byte{1}}, WriteTest{&bol, []byte{1}}, WriteTest{pBol, nil}, WriteTest{dateT, EncodeTime(dateT)}, WriteTest{&dateT, EncodeTime(dateT)}, WriteTest{pDateT, nil}, WriteTest{tstamp, EncodeTime(tstamp.Time)}, WriteTest{&tstamp, EncodeTime(tstamp.Time)}, WriteTest{pTstamp, nil}, WriteTest{date, EncodeDate(date)}, WriteTest{&date, EncodeDate(date)}, WriteTest{pDate, nil}, WriteTest{tim, EncodeDuration(tim)}, WriteTest{&tim, EncodeDuration(tim)}, WriteTest{pTim, nil}, WriteTest{Int, EncodeU32(uint32(Int))}, // Hack WriteTest{Int16, EncodeU16(uint16(Int16))}, WriteTest{Int32, EncodeU32(uint32(Int32))}, WriteTest{Int64, EncodeU64(uint64(Int64))}, WriteTest{Int, EncodeU32(uint32(Int))}, // Hack WriteTest{Uint16, EncodeU16(Uint16)}, WriteTest{Uint32, EncodeU32(Uint32)}, WriteTest{Uint64, EncodeU64(Uint64)}, WriteTest{&Int, EncodeU32(uint32(Int))}, // Hack WriteTest{&Int16, EncodeU16(uint16(Int16))}, WriteTest{&Int32, EncodeU32(uint32(Int32))}, WriteTest{&Int64, EncodeU64(uint64(Int64))}, WriteTest{&Uint, EncodeU32(uint32(Uint))}, // Hack WriteTest{&Uint16, EncodeU16(Uint16)}, WriteTest{&Uint32, EncodeU32(Uint32)}, WriteTest{&Uint64, EncodeU64(Uint64)}, WriteTest{pInt, nil}, WriteTest{pInt16, nil}, WriteTest{pInt32, nil}, WriteTest{pInt64, nil}, WriteTest{Float32, EncodeU32(math.Float32bits(Float32))}, WriteTest{Float64, EncodeU64(math.Float64bits(Float64))}, WriteTest{&Float32, EncodeU32(math.Float32bits(Float32))}, WriteTest{&Float64, EncodeU64(math.Float64bits(Float64))}, WriteTest{pFloat32, nil}, WriteTest{pFloat64, nil}, } }
func TestPrepared(t *testing.T) { myConnect(t, true, 0) query("drop table P") // Drop test table if exists checkResult(t, query( "create table P ("+ " ii int not null, ss varchar(20), dd datetime"+ ") default charset=utf8", ), cmdOK(0, false, true), ) exp := Stmt{ fields: []*mysql.Field{ &mysql.Field{ Catalog: "def", Db: "test", Table: "P", OrgTable: "P", Name: "i", OrgName: "ii", DispLen: 11, Flags: _FLAG_NO_DEFAULT_VALUE | _FLAG_NOT_NULL, Type: MYSQL_TYPE_LONG, Scale: 0, }, &mysql.Field{ Catalog: "def", Db: "test", Table: "P", OrgTable: "P", Name: "s", OrgName: "ss", DispLen: 3 * 20, // varchar(20) Flags: 0, Type: MYSQL_TYPE_VAR_STRING, Scale: 0, }, &mysql.Field{ Catalog: "def", Db: "test", Table: "P", OrgTable: "P", Name: "d", OrgName: "dd", DispLen: 19, Flags: _FLAG_BINARY, Type: MYSQL_TYPE_DATETIME, Scale: 0, }, }, fc_map: map[string]int{"i": 0, "s": 1, "d": 2}, field_count: 3, param_count: 2, warning_count: 0, status: 0x2, } sel := prepare("select ii i, ss s, dd d from P where ii = ? and ss = ?") checkStmt(t, sel, &StmtErr{&exp, nil}) all := prepare("select * from P") checkErr(t, all.err, nil) ins := prepare("insert into P values (?, ?, ?)") checkErr(t, ins.err, nil) parsed, err := mysql.ParseTime("2012-01-17 01:10:10", time.Local) checkErr(t, err, nil) parsedZero, err := mysql.ParseTime("0000-00-00 00:00:00", time.Local) checkErr(t, err, nil) if !parsedZero.IsZero() { t.Fatalf("time '%s' isn't zero", parsedZero) } exp_rows := []mysql.Row{ mysql.Row{ 2, "Taki tekst", time.Unix(123456789, 0), }, mysql.Row{ 5, "Pąk róży", parsed, }, mysql.Row{ 11, "Zero UTC datetime", time.Unix(0, 0), }, mysql.Row{ 17, mysql.Blob([]byte("Zero datetime")), parsedZero, }, mysql.Row{ 23, []byte("NULL datetime"), (*time.Time)(nil), }, mysql.Row{ 23, "NULL", nil, }, } for _, row := range exp_rows { checkErrWarn(t, exec(ins.stmt, row[0], row[1], row[2]), cmdOK(1, true, true), ) } // Convert values to expected result types for _, row := range exp_rows { for ii, col := range row { val := reflect.ValueOf(col) // Dereference pointers if val.Kind() == reflect.Ptr { val = val.Elem() } switch val.Kind() { case reflect.Invalid: row[ii] = nil case reflect.String: row[ii] = []byte(val.String()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: row[ii] = int32(val.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: row[ii] = int32(val.Uint()) case reflect.Slice: if val.Type().Elem().Kind() == reflect.Uint8 { bytes := make([]byte, val.Len()) for ii := range bytes { bytes[ii] = val.Index(ii).Interface().(uint8) } row[ii] = bytes } } } } checkErrWarn(t, exec(sel.stmt, 2, "Taki tekst"), selectOK(exp_rows, true)) checkErrWarnRows(t, exec(all.stmt), selectOK(exp_rows, true)) checkResult(t, query("drop table P"), cmdOK(0, false, true)) checkErr(t, sel.stmt.Delete(), nil) checkErr(t, all.stmt.Delete(), nil) checkErr(t, ins.stmt.Delete(), nil) myClose(t) }