예제 #1
0
func (t *table) fetchResult(itemT reflect.Type, rows *sql.Rows, columns []string) (item reflect.Value, err error) {
	expecting := len(columns)

	scanArgs := make([]interface{}, expecting)

	switch itemT.Kind() {
	case reflect.Struct:
		// Creating new value of the expected type.
		item = reflect.New(itemT)
		// Pairing each column with its index.
		for i, columnName := range columns {
			index := util.GetStructFieldIndex(itemT, columnName)
			if len(index) > 0 {
				destF := item.Elem().FieldByIndex(index)
				scanArgs[i] = destF.Addr().Interface()
			} else {
				var placeholder sql.RawBytes
				scanArgs[i] = &placeholder
			}
		}

		err = rows.Scan(scanArgs...)

		if err != nil {
			return item, err
		}
	case reflect.Map:
		values := make([]*sql.RawBytes, len(columns))
		for i := range columns {
			scanArgs[i] = &values[i]
		}
		err = rows.Scan(scanArgs...)

		if err == nil {
			item = reflect.MakeMap(itemT)
			for i, columnName := range columns {
				valS := string(*values[i])

				var vv reflect.Value

				if _, ok := t.columnTypes[columnName]; ok == true {
					v, _ := to.Convert(valS, t.columnTypes[columnName])
					vv = reflect.ValueOf(v)
				} else {
					v, _ := to.Convert(valS, reflect.String)
					vv = reflect.ValueOf(v)
				}

				vk := reflect.ValueOf(columnName)
				item.SetMapIndex(vk, vv)
			}
		}

		return item, err
	default:
		return item, db.ErrExpectingMapOrStruct
	}

	return item, nil
}
예제 #2
0
파일: util.go 프로젝트: vimdude/db
func (self *t) qlFetchResult(item_t reflect.Type, rows *sql.Rows, columns []string) (item reflect.Value, err error) {
	expecting := len(columns)

	scanArgs := make([]interface{}, expecting)

	switch item_t.Kind() {
	case reflect.Struct:
		// Creating new value of the expected type.
		item = reflect.New(item_t)
		// Pairing each column with its index.
		for i, columnName := range columns {
			index := util.GetStructFieldIndex(item_t, columnName)
			if index != nil {
				dest_f := item.Elem().FieldByIndex(index)
				scanArgs[i] = dest_f.Addr().Interface()
			}
		}

		err = rows.Scan(scanArgs...)

		if err != nil {
			return item, err
		}
	case reflect.Map:
		values := make([]*sql.RawBytes, len(columns))
		for i, _ := range columns {
			scanArgs[i] = &values[i]
		}
		err = rows.Scan(scanArgs...)

		if err == nil {
			item = reflect.MakeMap(item_t)
			for i, columnName := range columns {
				val_s := string(*values[i])

				var val_v reflect.Value

				if _, ok := self.ColumnTypes[columnName]; ok == true {
					v, _ := to.Convert(val_s, self.ColumnTypes[columnName])
					val_v = reflect.ValueOf(v)
				} else {
					v, _ := to.Convert(val_s, reflect.String)
					val_v = reflect.ValueOf(v)
				}

				key_v := reflect.ValueOf(columnName)
				item.SetMapIndex(key_v, val_v)
			}
		}

		return item, err
	default:
		return item, db.ErrExpectingMapOrStruct
	}

	return item, nil
}
예제 #3
0
파일: main.go 프로젝트: xiam/bridge
/*
	Tries to convert a value into the given type. If the conversion fails, a zero
	value is returned.
*/
func convertOrZero(val string, t reflect.Type) reflect.Value {

	z, err := to.Convert(val, t.Kind())

	if err == nil {
		return reflect.ValueOf(z)
	}

	return reflect.Zero(t)
}
예제 #4
0
파일: main_test.go 프로젝트: hiphoox/dig
/*
	Starts with src (pointer to Slice or Map) tries to follow the given route,
	if the route is found it then tries to copy or convert the found node into
	the value pointed by dst.
*/
func Get(src interface{}, dst interface{}, route ...interface{}) error {

	if len(route) < 1 {
		return fmt.Errorf("Missing route.")
	}

	dv := reflect.ValueOf(dst)

	if dv.Kind() != reflect.Ptr || dv.IsNil() {
		return fmt.Errorf("Destination is not a pointer.")
	}

	sv := reflect.ValueOf(src)

	if sv.Kind() != reflect.Ptr || sv.IsNil() {
		return fmt.Errorf("Source is not a pointer.")
	}

	// Setting to zero before setting it again.
	dv.Elem().Set(reflect.Zero(dv.Elem().Type()))

	p, err := pick(src, false, route...)

	if err != nil {
		return err
	}

	if p.IsValid() == false {
		return fmt.Errorf("Could not find route.")
	}

	if dv.Elem().Type() != p.Type() {
		// Trying conversion
		if p.CanInterface() == true {
			var t interface{}
			t, err = to.Convert(p.Interface(), dv.Elem().Kind())
			if err == nil {
				tv := reflect.ValueOf(t)
				if dv.Elem().Type() == tv.Type() {
					p = &tv
				}
			}
		}
	}

	if dv.Elem().Type() == p.Type() || dv.Elem().Kind() == reflect.Interface {
		dv.Elem().Set(*p)
	} else {
		return fmt.Errorf("Could not assign %s to %s.", p.Type(), dv.Elem().Type())
	}

	return nil
}
예제 #5
0
파일: main.go 프로젝트: icattlecoder/db
func StringToKind(src string, dstk reflect.Kind) (reflect.Value, error) {
	var srcv reflect.Value

	// Destination type.
	switch dstk {
	case reflect.Interface:
		// Destination is interface, nuff said.
		srcv = reflect.ValueOf(src)
	default:
		cv, err := to.Convert(src, dstk)
		if err != nil {
			return srcv, nil
		}
		srcv = reflect.ValueOf(cv)
	}

	return srcv, nil
}
예제 #6
0
파일: main.go 프로젝트: pzduniak/db
func (self *T) fetchResult(itemt reflect.Type, rows *sql.Rows, columns []string) (reflect.Value, error) {
	var err error

	var item reflect.Value

	expecting := len(columns)

	// Allocating results.
	values := make([]*sql.RawBytes, expecting)
	scanArgs := make([]interface{}, expecting)

	for i := range columns {
		scanArgs[i] = &values[i]
	}

	switch itemt.Kind() {
	case reflect.Map:
		item = reflect.MakeMap(itemt)
	case reflect.Struct:
		item = reflect.New(itemt)
	default:
		return item, db.ErrExpectingMapOrStruct
	}

	err = rows.Scan(scanArgs...)

	if err != nil {
		return item, err
	}

	// Range over row values.
	for i, value := range values {

		if value != nil {
			// Real column name
			column := columns[i]
			// Value as string.
			svalue := string(*value)

			var cv reflect.Value

			if _, ok := self.ColumnTypes[column]; ok == true {
				v, _ := to.Convert(svalue, self.ColumnTypes[column])
				cv = reflect.ValueOf(v)
			} else {
				v, _ := to.Convert(svalue, reflect.String)
				cv = reflect.ValueOf(v)
			}

			switch itemt.Kind() {
			// Destination is a map.
			case reflect.Map:
				if cv.Type() != itemt.Elem() {
					if itemt.Elem().Kind() == reflect.Interface {
						cv, _ = util.StringToType(svalue, cv.Type())
					} else {
						cv, _ = util.StringToType(svalue, itemt.Elem())
					}
				}
				if cv.IsValid() {
					item.SetMapIndex(reflect.ValueOf(column), cv)
				}
			// Destionation is a struct.
			case reflect.Struct:

				index := util.GetStructFieldIndex(itemt, column)

				if index == nil {
					continue
				} else {

					// Destination field.
					destf := item.Elem().FieldByIndex(index)

					if destf.IsValid() {
						if cv.Type() != destf.Type() {
							if destf.Type().Kind() != reflect.Interface {
								cv, _ = util.StringToType(svalue, destf.Type())
							}
						}
						// Copying value.
						if cv.IsValid() {
							destf.Set(cv)
						}
					}

				}
			}
		}
	}

	return item, nil
}
예제 #7
0
func fetchResult(itemT reflect.Type, rows *sql.Rows, columns []string) (reflect.Value, error) {
	var item reflect.Value
	var err error

	switch itemT.Kind() {
	case reflect.Map:
		item = reflect.MakeMap(itemT)
	case reflect.Struct:
		item = reflect.New(itemT)
	default:
		return item, db.ErrExpectingMapOrStruct
	}

	expecting := len(columns)

	// Allocating results.
	values := make([]*sql.RawBytes, expecting)
	scanArgs := make([]interface{}, expecting)

	for i := range columns {
		scanArgs[i] = &values[i]
	}

	if err = rows.Scan(scanArgs...); err != nil {
		return item, err
	}

	// Range over row values.
	for i, value := range values {

		if value != nil {
			// Real column name
			column := columns[i]

			// Value as string.
			svalue := string(*value)

			var cv reflect.Value

			v, _ := to.Convert(svalue, reflect.String)
			cv = reflect.ValueOf(v)

			switch itemT.Kind() {
			// Destination is a map.
			case reflect.Map:
				if cv.Type() != itemT.Elem() {
					if itemT.Elem().Kind() == reflect.Interface {
						cv, _ = util.StringToType(svalue, cv.Type())
					} else {
						cv, _ = util.StringToType(svalue, itemT.Elem())
					}
				}
				if cv.IsValid() {
					item.SetMapIndex(reflect.ValueOf(column), cv)
				}
			// Destionation is a struct.
			case reflect.Struct:

				index := util.GetStructFieldIndex(itemT, column)

				if index == nil {
					continue
				} else {

					// Destination field.
					destf := item.Elem().FieldByIndex(index)

					if destf.IsValid() {

						if cv.Type() != destf.Type() {

							if destf.Type().Kind() != reflect.Interface {

								switch destf.Type() {
								case nullFloat64Type:
									nullFloat64 := sql.NullFloat64{}
									if svalue != `` {
										nullFloat64.Scan(svalue)
									}
									cv = reflect.ValueOf(nullFloat64)
								case nullInt64Type:
									nullInt64 := sql.NullInt64{}
									if svalue != `` {
										nullInt64.Scan(svalue)
									}
									cv = reflect.ValueOf(nullInt64)
								case nullBoolType:
									nullBool := sql.NullBool{}
									if svalue != `` {
										nullBool.Scan(svalue)
									}
									cv = reflect.ValueOf(nullBool)
								case nullStringType:
									nullString := sql.NullString{}
									nullString.Scan(svalue)
									cv = reflect.ValueOf(nullString)
								default:
									var decodingNull bool

									if svalue == "" {
										decodingNull = true
									}

									u, _ := indirect(destf, decodingNull)

									if u != nil {
										u.UnmarshalDB(svalue)

										if destf.Kind() == reflect.Interface || destf.Kind() == reflect.Ptr {
											cv = reflect.ValueOf(u)
										} else {
											cv = reflect.ValueOf(u).Elem()
										}

									} else {
										cv, _ = util.StringToType(svalue, destf.Type())
									}

								}
							}

						}

						// Copying value.
						if cv.IsValid() {
							destf.Set(cv)
						}

					}
				}

			}
		}
	}

	return item, nil
}