package pgx

import (
	
	
	
	
	

	
	
)
CopyFromRows returns a CopyFromSource interface over the provided rows slice making it usable by *Conn.CopyFrom.
func ( [][]interface{}) CopyFromSource {
	return &copyFromRows{rows: , idx: -1}
}

type copyFromRows struct {
	rows [][]interface{}
	idx  int
}

func ( *copyFromRows) () bool {
	.idx++
	return .idx < len(.rows)
}

func ( *copyFromRows) () ([]interface{}, error) {
	return .rows[.idx], nil
}

func ( *copyFromRows) () error {
	return nil
}
CopyFromSlice returns a CopyFromSource interface over a dynamic func making it usable by *Conn.CopyFrom.
func ( int,  func(int) ([]interface{}, error)) CopyFromSource {
	return &copyFromSlice{next: , idx: -1, len: }
}

type copyFromSlice struct {
	next func(int) ([]interface{}, error)
	idx  int
	len  int
	err  error
}

func ( *copyFromSlice) () bool {
	.idx++
	return .idx < .len
}

func ( *copyFromSlice) () ([]interface{}, error) {
	,  := .next(.idx)
	if  != nil {
		.err = 
	}
	return , 
}

func ( *copyFromSlice) () error {
	return .err
}
CopyFromSource is the interface used by *Conn.CopyFrom as the source for copy data.
Next returns true if there is another row and makes the next row data available to Values(). When there are no more rows available or an error has occurred it returns false.
	Next() bool
Values returns the values for the current row.
	Values() ([]interface{}, error)
Err returns any error that has been encountered by the CopyFromSource. If this is not nil *Conn.CopyFrom will abort the copy.
	Err() error
}

type copyFrom struct {
	conn          *Conn
	tableName     Identifier
	columnNames   []string
	rowSrc        CopyFromSource
	readerErrChan chan error
}

func ( *copyFrom) ( context.Context) (int64, error) {
	 := .tableName.Sanitize()
	 := &bytes.Buffer{}
	for ,  := range .columnNames {
		if  != 0 {
			.WriteString(", ")
		}
		.WriteString(quoteIdentifier())
	}
	 := .String()

	,  := .conn.Prepare(, "", fmt.Sprintf("select %s from %s", , ))
	if  != nil {
		return 0, 
	}

	,  := io.Pipe()
	 := make(chan struct{})

	go func() {
		defer close()
Purposely NOT using defer w.Close(). See https://github.com/golang/go/issues/24283.
		 := .conn.wbuf

		 = append(, "PGCOPY\n\377\r\n\000"...)
		 = pgio.AppendInt32(, 0)
		 = pgio.AppendInt32(, 0)

		 := true
		for  {
			var  error
			, ,  = .buildCopyBuf(, )
			if  != nil {
				.CloseWithError()
				return
			}

			if .rowSrc.Err() != nil {
				.CloseWithError(.rowSrc.Err())
				return
			}

			if len() > 0 {
				_,  = .Write()
				if  != nil {
					.Close()
					return
				}
			}

			 = [:0]
		}

		.Close()
	}()

	 := time.Now()

	,  := .conn.pgConn.CopyFrom(, , fmt.Sprintf("copy %s ( %s ) from stdin binary;", , ))

	.Close()
	<-

	 := .RowsAffected()
	if  == nil {
		if .conn.shouldLog(LogLevelInfo) {
			 := time.Now()
			.conn.log(, LogLevelInfo, "CopyFrom", map[string]interface{}{"tableName": .tableName, "columnNames": .columnNames, "time": .Sub(), "rowCount": })
		}
	} else if .conn.shouldLog(LogLevelError) {
		.conn.log(, LogLevelError, "CopyFrom", map[string]interface{}{"err": , "tableName": .tableName, "columnNames": .columnNames})
	}

	return , 
}

func ( *copyFrom) ( []byte,  *pgconn.StatementDescription) (bool, []byte, error) {

	for .rowSrc.Next() {
		,  := .rowSrc.Values()
		if  != nil {
			return false, nil, 
		}
		if len() != len(.columnNames) {
			return false, nil, fmt.Errorf("expected %d values, got %d values", len(.columnNames), len())
		}

		 = pgio.AppendInt16(, int16(len(.columnNames)))
		for ,  := range  {
			,  = encodePreparedStatementArgument(.conn.connInfo, , .Fields[].DataTypeOID, )
			if  != nil {
				return false, nil, 
			}
		}

		if len() > 65536 {
			return true, , nil
		}
	}

	return false, , nil
}
CopyFrom uses the PostgreSQL copy protocol to perform bulk data insertion. It returns the number of rows copied and an error. CopyFrom requires all values use the binary format. Almost all types implemented by pgx use the binary format by default. Types implementing Encoder can only be used if they encode to the binary format.
func ( *Conn) ( context.Context,  Identifier,  []string,  CopyFromSource) (int64, error) {
	 := &copyFrom{
		conn:          ,
		tableName:     ,
		columnNames:   ,
		rowSrc:        ,
		readerErrChan: make(chan error),
	}

	return .run()