Ejemplo n.º 1
0
func (db *DB) rawSelectByStruct(structType reflect.Type, qi SqlQueryInfo) (rows *sql.Rows, fields []string, err error) {
	// nums of struct's fields
	lf := structType.NumField()
	// type's fields
	fields = make([]string, 0, lf)
	// sql select columns, it's Snake Cased
	columns := make([]string, 0, lf)

	// get fields in structType,
	// and convert to sql query column name
	for i := 0; i < lf; i++ {
		structField := structType.Field(i)
		if structField.Type.Kind() != reflect.Func && structField.Tag.Get("db") != "exclude" {
			fieldName := structField.Name
			fields = append(fields, fieldName)
			columns = append(columns, "`"+utils.SnakeCasedName(fieldName)+"`")
		}
	}

	tableName := utils.SnakeCasedName(structType.Name())

	// TODO: check the fileds has specified ?
	qi.Fields = strings.Join(columns, ", ")
	// run query from db
	rows, err = db.Select(tableName, qi)
	return
}
Ejemplo n.º 2
0
// insert struct to database
// if i is pointer to struct and has a int type field named "Id"
// the field "Id" will set to the last insert id if has LastInsertId
//
// field mapping rule is: HelloWorld => hello_world
// mean that struct's field "HelloWorld" in database table's field is "hello_world"
// table name mapping use the same rule as field
func (db *DB) InsertStruct(i interface{}) (sql.Result, error) {
	m := utils.StructToSnakeKeyMap(i)
	table := utils.SnakeCasedName(utils.StructName(i))
	r, err := db.Insert(table, m)

	if err == nil {
		insertId, err2 := r.LastInsertId()
		if err2 == nil && insertId > 0 {
			ps := reflect.ValueOf(i)
			if ps.Kind() == reflect.Ptr {
				// struct
				s := ps.Elem()
				if s.Kind() == reflect.Struct {
					// exported field
					f := s.FieldByName("Id")
					if f.IsValid() {
						// A Value can be changed only if it is
						// addressable and was not obtained by
						// the use of unexported struct fields.
						if f.CanSet() {
							// change value of N
							k := f.Kind()
							if k == reflect.Int || k == reflect.Int32 || k == reflect.Int64 {
								if !f.OverflowInt(insertId) {
									f.SetInt(insertId)
								}
							}
						}
					}
				}
			}
		}
	}
	return r, err
}