PageRenderTime 86ms CodeModel.GetById 34ms app.highlight 48ms RepoModel.GetById 1ms app.codeStats 0ms

/Godeps/_workspace/src/github.com/ziutek/mymysql/mysql/row.go

https://gitlab.com/voxxit/gogeoip2
Go | 475 lines | 366 code | 36 blank | 73 comment | 65 complexity | 45582726f84c0336ed41f0b9bf5a711d MD5 | raw file
  1package mysql
  2
  3import (
  4	"bytes"
  5	"errors"
  6	"fmt"
  7	"math"
  8	"os"
  9	"reflect"
 10	"strconv"
 11	"time"
 12)
 13
 14// Result row - contains values for any column of received row.
 15//
 16// If row is a result of ordinary text query, its element can be
 17// []byte slice, contained result text or nil if NULL is returned.
 18//
 19// If it is result of prepared statement execution, its element field can be:
 20// intX, uintX, floatX, []byte, Date, Time, time.Time (in Local location) or nil
 21type Row []interface{}
 22
 23// Get the nn-th value and return it as []byte ([]byte{} if NULL)
 24func (tr Row) Bin(nn int) (bin []byte) {
 25	switch data := tr[nn].(type) {
 26	case nil:
 27		// bin = []byte{}
 28	case []byte:
 29		bin = data
 30	default:
 31		buf := new(bytes.Buffer)
 32		fmt.Fprint(buf, data)
 33		bin = buf.Bytes()
 34	}
 35	return
 36}
 37
 38// Get the nn-th value and return it as string ("" if NULL)
 39func (tr Row) Str(nn int) (str string) {
 40	switch data := tr[nn].(type) {
 41	case nil:
 42		// str = ""
 43	case []byte:
 44		str = string(data)
 45	case time.Time:
 46		str = TimeString(data)
 47	case time.Duration:
 48		str = DurationString(data)
 49	default:
 50		str = fmt.Sprint(data)
 51	}
 52	return
 53}
 54
 55const _MAX_INT = int64(int(^uint(0) >> 1))
 56const _MIN_INT = -_MAX_INT - 1
 57
 58// Get the nn-th value and return it as int (0 if NULL). Return error if
 59// conversion is impossible.
 60func (tr Row) IntErr(nn int) (val int, err error) {
 61	switch data := tr[nn].(type) {
 62	case nil:
 63		// nop
 64	case int32:
 65		val = int(data)
 66	case int16:
 67		val = int(data)
 68	case uint16:
 69		val = int(data)
 70	case int8:
 71		val = int(data)
 72	case uint8:
 73		val = int(data)
 74	case []byte:
 75		val, err = strconv.Atoi(string(data))
 76	case int64:
 77		if data >= _MIN_INT && data <= _MAX_INT {
 78			val = int(data)
 79		} else {
 80			err = strconv.ErrRange
 81		}
 82	case uint32:
 83		if int64(data) <= _MAX_INT {
 84			val = int(data)
 85		} else {
 86			err = strconv.ErrRange
 87		}
 88	case uint64:
 89		if data <= uint64(_MAX_INT) {
 90			val = int(data)
 91		} else {
 92			err = strconv.ErrRange
 93		}
 94	default:
 95		err = os.ErrInvalid
 96	}
 97	return
 98}
 99
100// Get the nn-th value and return it as int (0 if NULL). Panic if conversion is
101// impossible.
102func (tr Row) Int(nn int) (val int) {
103	val, err := tr.IntErr(nn)
104	if err != nil {
105		panic(err)
106	}
107	return
108}
109
110// Get the nn-th value and return it as int. Return 0 if value is NULL or
111// conversion is impossible.
112func (tr Row) ForceInt(nn int) (val int) {
113	val, _ = tr.IntErr(nn)
114	return
115}
116
117const _MAX_UINT = uint64(^uint(0))
118
119// Get the nn-th value and return it as uint (0 if NULL). Return error if
120// conversion is impossible.
121func (tr Row) UintErr(nn int) (val uint, err error) {
122	switch data := tr[nn].(type) {
123	case nil:
124		// nop
125	case uint32:
126		val = uint(data)
127	case uint16:
128		val = uint(data)
129	case uint8:
130		val = uint(data)
131	case []byte:
132		var v uint64
133		v, err = strconv.ParseUint(string(data), 0, 0)
134		val = uint(v)
135	case uint64:
136		if data <= _MAX_UINT {
137			val = uint(data)
138		} else {
139			err = strconv.ErrRange
140		}
141	case int8, int16, int32, int64:
142		v := reflect.ValueOf(data).Int()
143		if v >= 0 && uint64(v) <= _MAX_UINT {
144			val = uint(v)
145		} else {
146			err = strconv.ErrRange
147		}
148	default:
149		err = os.ErrInvalid
150	}
151	return
152}
153
154// Get the nn-th value and return it as uint (0 if NULL). Panic if conversion is
155// impossible.
156func (tr Row) Uint(nn int) (val uint) {
157	val, err := tr.UintErr(nn)
158	if err != nil {
159		panic(err)
160	}
161	return
162}
163
164// Get the nn-th value and return it as uint. Return 0 if value is NULL or
165// conversion is impossible.
166func (tr Row) ForceUint(nn int) (val uint) {
167	val, _ = tr.UintErr(nn)
168	return
169}
170
171// Get the nn-th value and return it as Date (0000-00-00 if NULL). Return error
172// if conversion is impossible.
173func (tr Row) DateErr(nn int) (val Date, err error) {
174	switch data := tr[nn].(type) {
175	case nil:
176		// nop
177	case Date:
178		val = data
179	case []byte:
180		val, err = ParseDate(string(data))
181	}
182	return
183}
184
185// It is like DateErr but panics if conversion is impossible.
186func (tr Row) Date(nn int) (val Date) {
187	val, err := tr.DateErr(nn)
188	if err != nil {
189		panic(err)
190	}
191	return
192}
193
194// It is like DateErr but return 0000-00-00 if conversion is impossible.
195func (tr Row) ForceDate(nn int) (val Date) {
196	val, _ = tr.DateErr(nn)
197	return
198}
199
200// Get the nn-th value and return it as time.Time in loc location (zero if NULL)
201// Returns error if conversion is impossible. It can convert Date to time.Time.
202func (tr Row) TimeErr(nn int, loc *time.Location) (t time.Time, err error) {
203	switch data := tr[nn].(type) {
204	case nil:
205		// nop
206	case time.Time:
207		if loc == time.Local {
208			t = data
209		} else {
210			y, mon, d := data.Date()
211			h, m, s := data.Clock()
212			t = time.Date(y, mon, d, h, m, s, t.Nanosecond(), loc)
213		}
214	case Date:
215		t = data.Time(loc)
216	case []byte:
217		t, err = ParseTime(string(data), loc)
218	}
219	return
220}
221
222// As TimeErr but panics if conversion is impossible.
223func (tr Row) Time(nn int, loc *time.Location) (val time.Time) {
224	val, err := tr.TimeErr(nn, loc)
225	if err != nil {
226		panic(err)
227	}
228	return
229}
230
231// It is like TimeErr but returns 0000-00-00 00:00:00 if conversion is
232// impossible.
233func (tr Row) ForceTime(nn int, loc *time.Location) (val time.Time) {
234	val, _ = tr.TimeErr(nn, loc)
235	return
236}
237
238// Get the nn-th value and return it as time.Time in Local location
239// (zero if NULL). Returns error if conversion is impossible.
240// It can convert Date to time.Time.
241func (tr Row) LocaltimeErr(nn int) (t time.Time, err error) {
242	switch data := tr[nn].(type) {
243	case nil:
244		// nop
245	case time.Time:
246		t = data
247	case Date:
248		t = data.Time(time.Local)
249	case []byte:
250		t, err = ParseTime(string(data), time.Local)
251	}
252	return
253}
254
255// As LocaltimeErr but panics if conversion is impossible.
256func (tr Row) Localtime(nn int) (val time.Time) {
257	val, err := tr.LocaltimeErr(nn)
258	if err != nil {
259		panic(err)
260	}
261	return
262}
263
264// It is like LocaltimeErr but returns 0000-00-00 00:00:00 if conversion is
265// impossible.
266func (tr Row) ForceLocaltime(nn int) (val time.Time) {
267	val, _ = tr.LocaltimeErr(nn)
268	return
269}
270
271// Get the nn-th value and return it as time.Duration (0 if NULL). Return error
272// if conversion is impossible.
273func (tr Row) DurationErr(nn int) (val time.Duration, err error) {
274	switch data := tr[nn].(type) {
275	case nil:
276	case time.Duration:
277		val = data
278	case []byte:
279		val, err = ParseDuration(string(data))
280	default:
281		err = errors.New(
282			fmt.Sprintf("Can't convert `%v` to time.Duration", data),
283		)
284	}
285	return
286}
287
288// It is like DurationErr but panics if conversion is impossible.
289func (tr Row) Duration(nn int) (val time.Duration) {
290	val, err := tr.DurationErr(nn)
291	if err != nil {
292		panic(err)
293	}
294	return
295}
296
297// It is like DurationErr but return 0 if conversion is impossible.
298func (tr Row) ForceDuration(nn int) (val time.Duration) {
299	val, _ = tr.DurationErr(nn)
300	return
301}
302
303// Get the nn-th value and return it as bool. Return error
304// if conversion is impossible.
305func (tr Row) BoolErr(nn int) (val bool, err error) {
306	switch data := tr[nn].(type) {
307	case nil:
308		// nop
309	case int8:
310		val = (data != 0)
311	case int32:
312		val = (data != 0)
313	case int16:
314		val = (data != 0)
315	case int64:
316		val = (data != 0)
317	case uint8:
318		val = (data != 0)
319	case uint32:
320		val = (data != 0)
321	case uint16:
322		val = (data != 0)
323	case uint64:
324		val = (data != 0)
325	case []byte:
326		var v int64
327		v, err = strconv.ParseInt(string(data), 0, 64)
328		val = (v != 0)
329	default:
330		err = os.ErrInvalid
331	}
332	return
333}
334
335// It is like BoolErr but panics if conversion is impossible.
336func (tr Row) Bool(nn int) (val bool) {
337	val, err := tr.BoolErr(nn)
338	if err != nil {
339		panic(err)
340	}
341	return
342}
343
344// It is like BoolErr but return false if conversion is impossible.
345func (tr Row) ForceBool(nn int) (val bool) {
346	val, _ = tr.BoolErr(nn)
347	return
348}
349
350// Get the nn-th value and return it as int64 (0 if NULL). Return error if
351// conversion is impossible.
352func (tr Row) Int64Err(nn int) (val int64, err error) {
353	switch data := tr[nn].(type) {
354	case nil:
355		// nop
356	case int64, int32, int16, int8:
357		val = reflect.ValueOf(data).Int()
358	case uint64, uint32, uint16, uint8:
359		u := reflect.ValueOf(data).Uint()
360		if u > math.MaxInt64 {
361			err = strconv.ErrRange
362		} else {
363			val = int64(u)
364		}
365	case []byte:
366		val, err = strconv.ParseInt(string(data), 10, 64)
367	default:
368		err = os.ErrInvalid
369	}
370	return
371}
372
373// Get the nn-th value and return it as int64 (0 if NULL).
374// Panic if conversion is impossible.
375func (tr Row) Int64(nn int) (val int64) {
376	val, err := tr.Int64Err(nn)
377	if err != nil {
378		panic(err)
379	}
380	return
381}
382
383// Get the nn-th value and return it as int64. Return 0 if value is NULL or
384// conversion is impossible.
385func (tr Row) ForceInt64(nn int) (val int64) {
386	val, _ = tr.Int64Err(nn)
387	return
388}
389
390// Get the nn-th value and return it as uint64 (0 if NULL). Return error if
391// conversion is impossible.
392func (tr Row) Uint64Err(nn int) (val uint64, err error) {
393	switch data := tr[nn].(type) {
394	case nil:
395		// nop
396	case uint64, uint32, uint16, uint8:
397		val = reflect.ValueOf(data).Uint()
398	case int64, int32, int16, int8:
399		i := reflect.ValueOf(data).Int()
400		if i < 0 {
401			err = strconv.ErrRange
402		} else {
403			val = uint64(i)
404		}
405	case []byte:
406		val, err = strconv.ParseUint(string(data), 10, 64)
407	default:
408		err = os.ErrInvalid
409	}
410	return
411}
412
413// Get the nn-th value and return it as uint64 (0 if NULL).
414// Panic if conversion is impossible.
415func (tr Row) Uint64(nn int) (val uint64) {
416	val, err := tr.Uint64Err(nn)
417	if err != nil {
418		panic(err)
419	}
420	return
421}
422
423// Get the nn-th value and return it as uint64. Return 0 if value is NULL or
424// conversion is impossible.
425func (tr Row) ForceUint64(nn int) (val uint64) {
426	val, _ = tr.Uint64Err(nn)
427	return
428}
429
430// Get the nn-th value and return it as float64 (0 if NULL). Return error if
431// conversion is impossible.
432func (tr Row) FloatErr(nn int) (val float64, err error) {
433	switch data := tr[nn].(type) {
434	case nil:
435		// nop
436	case float64, float32:
437		val = reflect.ValueOf(data).Float()
438	case int64, int32, int16, int8:
439		i := reflect.ValueOf(data).Int()
440		if i >= 2<<53 || i <= -(2<<53) {
441			err = strconv.ErrRange
442		} else {
443			val = float64(i)
444		}
445	case uint64, uint32, uint16, uint8:
446		u := reflect.ValueOf(data).Uint()
447		if u >= 2<<53 {
448			err = strconv.ErrRange
449		} else {
450			val = float64(u)
451		}
452	case []byte:
453		val, err = strconv.ParseFloat(string(data), 64)
454	default:
455		err = os.ErrInvalid
456	}
457	return
458}
459
460// Get the nn-th value and return it as float64 (0 if NULL).
461// Panic if conversion is impossible.
462func (tr Row) Float(nn int) (val float64) {
463	val, err := tr.FloatErr(nn)
464	if err != nil {
465		panic(err)
466	}
467	return
468}
469
470// Get the nn-th value and return it as float64. Return 0 if value is NULL or
471// if conversion is impossible.
472func (tr Row) ForceFloat(nn int) (val float64) {
473	val, _ = tr.FloatErr(nn)
474	return
475}