package gorm

import (
	
	
	
	

	
	
)

// prepareValues prepare values slice
func prepareValues( []interface{},  *DB,  []*sql.ColumnType,  []string) {
	if .Statement.Schema != nil {
		for ,  := range  {
			if  := .Statement.Schema.LookUpField();  != nil {
				[] = reflect.New(reflect.PtrTo(.FieldType)).Interface()
				continue
			}
			[] = new(interface{})
		}
	} else if len() > 0 {
		for ,  := range  {
			if .ScanType() != nil {
				[] = reflect.New(reflect.PtrTo(.ScanType())).Interface()
			} else {
				[] = new(interface{})
			}
		}
	} else {
		for  := range  {
			[] = new(interface{})
		}
	}
}

func scanIntoMap( map[string]interface{},  []interface{},  []string) {
	for ,  := range  {
		if  := reflect.Indirect(reflect.Indirect(reflect.ValueOf([]))); .IsValid() {
			[] = .Interface()
			if ,  := [].(driver.Valuer);  {
				[], _ = .Value()
			} else if ,  := [].(sql.RawBytes);  {
				[] = string()
			}
		} else {
			[] = nil
		}
	}
}

func ( *DB) ( Rows,  reflect.Value,  []interface{},  []*schema.Field,  [][]*schema.Field) {
	for ,  := range  {
		if  != nil {
			[] = .NewValuePool.Get()
		} else if len() == 1 {
			if .CanAddr() {
				[] = .Addr().Interface()
			} else {
				[] = .Interface()
			}
		}
	}

	.RowsAffected++
	.AddError(.Scan(...))
	 := make(map[string]interface{})
	for ,  := range  {
		if  == nil {
			continue
		}

		if len() == 0 || len([]) == 0 {
			.AddError(.Set(.Statement.Context, , []))
		} else { // joinFields count is larger than 2 when using join
			var  bool
			var  reflect.Value
			// does not contain raw dbname
			 := [][:len([])-1]
			// current reflect value
			 := 
			 := make([]string, 0, len())
			for ,  := range  {
				 = append(, .Name)
				 = .ReflectValueOf(.Statement.Context, )
				if .Kind() == reflect.Ptr {
					 := utils.JoinNestedRelationNames()
					// same nested structure
					if ,  := []; ! {
						if  := reflect.ValueOf([]).Elem(); .Kind() == reflect.Ptr && .IsNil() {
							 = true
							break
						}

						.Set(reflect.New(.Type().Elem()))
						[] = nil
					}
				}
				 = 
			}

			if ! { // ignore if value is nil
				 := [][len([])-1]
				.AddError(.Set(.Statement.Context, , []))
			}
		}

		// release data to pool
		.NewValuePool.Put([])
	}
}

// ScanMode scan data mode
type ScanMode uint8

// scan modes
const (
	ScanInitialized         ScanMode = 1 << 0 // 1
	ScanUpdate              ScanMode = 1 << 1 // 2
	ScanOnConflictDoNothing ScanMode = 1 << 2 // 4
)

// Scan scan rows into db statement
func ( Rows,  *DB,  ScanMode) {
	var (
		,           = .Columns()
		              = make([]interface{}, len())
		         = &ScanInitialized != 0
		              = &ScanUpdate != 0
		 = &ScanOnConflictDoNothing != 0
	)

	.RowsAffected = 0

	switch dest := .Statement.Dest.(type) {
	case map[string]interface{}, *map[string]interface{}:
		if  || .Next() {
			,  := .ColumnTypes()
			prepareValues(, , , )

			.RowsAffected++
			.AddError(.Scan(...))

			,  := .(map[string]interface{})
			if ! {
				if ,  := .(*map[string]interface{});  {
					if * == nil {
						* = map[string]interface{}{}
					}
					 = *
				}
			}
			scanIntoMap(, , )
		}
	case *[]map[string]interface{}:
		,  := .ColumnTypes()
		for  || .Next() {
			prepareValues(, , , )

			 = false
			.RowsAffected++
			.AddError(.Scan(...))

			 := map[string]interface{}{}
			scanIntoMap(, , )
			* = append(*, )
		}
	case *int, *int8, *int16, *int32, *int64,
		*uint, *uint8, *uint16, *uint32, *uint64, *uintptr,
		*float32, *float64,
		*bool, *string, *time.Time,
		*sql.NullInt32, *sql.NullInt64, *sql.NullFloat64,
		*sql.NullBool, *sql.NullString, *sql.NullTime:
		for  || .Next() {
			 = false
			.RowsAffected++
			.AddError(.Scan())
		}
	default:
		var (
			       = make([]*schema.Field, len())
			   [][]*schema.Field
			          = .Statement.Schema
			 = .Statement.ReflectValue
		)

		if .Kind() == reflect.Interface {
			 = .Elem()
		}

		 := .Type()
		switch .Kind() {
		case reflect.Array, reflect.Slice:
			 = .Elem()
		}
		 := .Kind() == reflect.Ptr
		if  {
			 = .Elem()
		}

		if  != nil {
			if  != .ModelType && .Kind() == reflect.Struct {
				, _ = schema.Parse(.Statement.Dest, .cacheStore, .NamingStrategy)
			}

			if len() == 1 {
				// Is Pluck
				if ,  := reflect.New().Interface().(sql.Scanner); ( != .ModelType && ) || // is scanner
					.Kind() != reflect.Struct || // is not struct
					.ModelType.ConvertibleTo(schema.TimeReflectType) { // is time
					 = nil
				}
			}

			// Not Pluck
			if  != nil {
				 := make(map[string]int, len())
				for ,  := range  {
					if  := .LookUpField();  != nil && .Readable {
						[] = 
						if ,  := [];  {
							// handle duplicate fields
							for ,  := range .Fields {
								if .DBName ==  && .Readable {
									if  == 0 {
										[]++
										[] = 
										break
									}
									--
								}
							}
						} else {
							[] = 1
						}
					} else if  := utils.SplitNestedRelationName(); len() > 1 { // has nested relation
						if ,  := .Relationships.Relations[[0]];  {
							 := len()
							// nested relation fields
							 := make([]*schema.Field, 0, -1)
							 = append(, .Field)
							for ,  := range [1 : -1] {
								 = .FieldSchema.Relationships.Relations[]
								 = append(, .Field)
							}
							// lastest name is raw dbname
							 := [-1]
							if  := .FieldSchema.LookUpField();  != nil && .Readable {
								[] = 

								if len() == 0 {
									 = make([][]*schema.Field, len())
								}
								 = append(, )
								[] = 
								continue
							}
						}
						[] = &sql.RawBytes{}
					} else {
						[] = &sql.RawBytes{}
					}
				}
			}
		}

		switch .Kind() {
		case reflect.Slice, reflect.Array:
			var (
				        reflect.Value
				 = .Kind() == reflect.Array
			)

			if ! || .Len() == 0 {
				 = false
				// if the slice cap is externally initialized, the externally initialized slice is directly used here
				if .Cap() == 0 {
					.Statement.ReflectValue.Set(reflect.MakeSlice(.Type(), 0, 20))
				} else if ! {
					.SetLen(0)
					.Statement.ReflectValue.Set()
				}
			}

			for  || .Next() {
			:
				 = false

				if  {
					if int(.RowsAffected) >= .Len() {
						return
					}
					 = .Index(int(.RowsAffected))
					if  {
						for ,  := range  {
							if ,  := .ValueOf(.Statement.Context, ); ! {
								.RowsAffected++
								goto 
							}
						}
					}
				} else {
					 = reflect.New()
				}

				.scanIntoStruct(, , , , )

				if ! {
					if ! {
						 = .Elem()
					}
					if  {
						if .Len() >= int(.RowsAffected) {
							.Index(int(.RowsAffected - 1)).Set()
						}
					} else {
						 = reflect.Append(, )
					}
				}
			}

			if ! {
				.Statement.ReflectValue.Set()
			}
		case reflect.Struct, reflect.Ptr:
			if  || .Next() {
				.scanIntoStruct(, , , , )
			}
		default:
			.AddError(.Scan())
		}
	}

	if  := .Err();  != nil &&  != .Error {
		.AddError()
	}

	if .RowsAffected == 0 && .Statement.RaiseErrorOnNotFound && .Error == nil {
		.AddError(ErrRecordNotFound)
	}
}