PageRenderTime 68ms CodeModel.GetById 32ms app.highlight 29ms RepoModel.GetById 2ms app.codeStats 0ms

/Godeps/_workspace/src/github.com/ziutek/mymysql/native/paramvalue.go

https://gitlab.com/voxxit/gogeoip2
Go | 161 lines | 127 code | 24 blank | 10 comment | 29 complexity | 79855241a773ecc6e63fde5e1aaa3289 MD5 | raw file
  1package native
  2
  3import (
  4	"github.com/ziutek/mymysql/mysql"
  5	"math"
  6	"reflect"
  7	"time"
  8)
  9
 10type paramValue struct {
 11	typ    uint16
 12	addr   reflect.Value
 13	raw    bool
 14	length int // >=0 - length of value, <0 - unknown length
 15}
 16
 17func (val *paramValue) Len() int {
 18	if !val.addr.IsValid() {
 19		// Invalid Value was binded
 20		return 0
 21	}
 22	// val.addr always points to the pointer - lets dereference it
 23	v := val.addr.Elem()
 24	if v.IsNil() {
 25		// Binded Ptr Value is nil
 26		return 0
 27	}
 28	v = v.Elem()
 29
 30	if val.length >= 0 {
 31		return val.length
 32	}
 33
 34	switch val.typ {
 35	case MYSQL_TYPE_STRING:
 36		return lenStr(v.String())
 37
 38	case MYSQL_TYPE_DATE:
 39		return lenDate(v.Interface().(mysql.Date))
 40
 41	case MYSQL_TYPE_TIMESTAMP:
 42		return lenTime(v.Interface().(mysql.Timestamp).Time)
 43	case MYSQL_TYPE_DATETIME:
 44		return lenTime(v.Interface().(time.Time))
 45
 46	case MYSQL_TYPE_TIME:
 47		return lenDuration(v.Interface().(time.Duration))
 48
 49	case MYSQL_TYPE_TINY: // val.length < 0 so this is bool
 50		return 1
 51	}
 52	// MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_BLOB and type of Raw value
 53	return lenBin(v.Bytes())
 54}
 55
 56func (pw *pktWriter) writeValue(val *paramValue) {
 57	if !val.addr.IsValid() {
 58		// Invalid Value was binded
 59		return
 60	}
 61	// val.addr always points to the pointer - lets dereference it
 62	v := val.addr.Elem()
 63	if v.IsNil() {
 64		// Binded Ptr Value is nil
 65		return
 66	}
 67	v = v.Elem()
 68
 69	if val.raw || val.typ == MYSQL_TYPE_VAR_STRING ||
 70		val.typ == MYSQL_TYPE_BLOB {
 71		pw.writeBin(v.Bytes())
 72		return
 73	}
 74	// We don't need unsigned bit to check type
 75	unsign := (val.typ & MYSQL_UNSIGNED_MASK) != 0
 76	switch val.typ & ^MYSQL_UNSIGNED_MASK {
 77	case MYSQL_TYPE_NULL:
 78		// Don't write null values
 79
 80	case MYSQL_TYPE_STRING:
 81		pw.writeBin([]byte(v.String()))
 82
 83	case MYSQL_TYPE_LONG:
 84		i := v.Interface()
 85		if unsign {
 86			l, ok := i.(uint32)
 87			if !ok {
 88				l = uint32(i.(uint))
 89			}
 90			pw.writeU32(l)
 91		} else {
 92			l, ok := i.(int32)
 93			if !ok {
 94				l = int32(i.(int))
 95			}
 96			pw.writeU32(uint32(l))
 97		}
 98
 99	case MYSQL_TYPE_FLOAT:
100		pw.writeU32(math.Float32bits(v.Interface().(float32)))
101
102	case MYSQL_TYPE_SHORT:
103		if unsign {
104			pw.writeU16(v.Interface().(uint16))
105		} else {
106			pw.writeU16(uint16(v.Interface().(int16)))
107
108		}
109
110	case MYSQL_TYPE_TINY:
111		if val.length == -1 {
112			// Translate bool value to MySQL tiny
113			if v.Bool() {
114				pw.writeByte(1)
115			} else {
116				pw.writeByte(0)
117			}
118		} else {
119			if unsign {
120				pw.writeByte(v.Interface().(uint8))
121			} else {
122				pw.writeByte(uint8(v.Interface().(int8)))
123			}
124		}
125
126	case MYSQL_TYPE_LONGLONG:
127		i := v.Interface()
128		if unsign {
129			l, ok := i.(uint64)
130			if !ok {
131				l = uint64(i.(uint))
132			}
133			pw.writeU64(l)
134		} else {
135			l, ok := i.(int64)
136			if !ok {
137				l = int64(i.(int))
138			}
139			pw.writeU64(uint64(l))
140		}
141
142	case MYSQL_TYPE_DOUBLE:
143		pw.writeU64(math.Float64bits(v.Interface().(float64)))
144
145	case MYSQL_TYPE_DATE:
146		pw.writeDate(v.Interface().(mysql.Date))
147
148	case MYSQL_TYPE_TIMESTAMP:
149		pw.writeTime(v.Interface().(mysql.Timestamp).Time)
150
151	case MYSQL_TYPE_DATETIME:
152		pw.writeTime(v.Interface().(time.Time))
153
154	case MYSQL_TYPE_TIME:
155		pw.writeDuration(v.Interface().(time.Duration))
156
157	default:
158		panic(mysql.ErrBindUnkType)
159	}
160	return
161}