package sqlite3

import (
	
	

	
)

// Stmt is a prepared statement object.
//
// https://sqlite.org/c3ref/stmt.html
type Stmt struct {
	c      *Conn
	err    error
	sql    string
	handle ptr_t
}

// Close destroys the prepared statement object.
//
// It is safe to close a nil, zero or closed Stmt.
//
// https://sqlite.org/c3ref/finalize.html
func ( *Stmt) () error {
	if  == nil || .handle == 0 {
		return nil
	}

	 := res_t(.c.call("sqlite3_finalize", stk_t(.handle)))
	 := .c.stmts
	for  := range  {
		if  == [] {
			 := len() - 1
			[] = []
			[] = nil
			.c.stmts = [:]
			break
		}
	}

	.handle = 0
	return .c.error()
}

// Conn returns the database connection to which the prepared statement belongs.
//
// https://sqlite.org/c3ref/db_handle.html
func ( *Stmt) () *Conn {
	return .c
}

// SQL returns the SQL text used to create the prepared statement.
//
// https://sqlite.org/c3ref/expanded_sql.html
func ( *Stmt) () string {
	return .sql
}

// ExpandedSQL returns the SQL text of the prepared statement
// with bound parameters expanded.
//
// https://sqlite.org/c3ref/expanded_sql.html
func ( *Stmt) () string {
	 := ptr_t(.c.call("sqlite3_expanded_sql", stk_t(.handle)))
	 := util.ReadString(.c.mod, , _MAX_SQL_LENGTH)
	.c.free()
	return 
}

// ReadOnly returns true if and only if the statement
// makes no direct changes to the content of the database file.
//
// https://sqlite.org/c3ref/stmt_readonly.html
func ( *Stmt) () bool {
	 := int32(.c.call("sqlite3_stmt_readonly", stk_t(.handle)))
	return  != 0
}

// Reset resets the prepared statement object.
//
// https://sqlite.org/c3ref/reset.html
func ( *Stmt) () error {
	 := res_t(.c.call("sqlite3_reset", stk_t(.handle)))
	.err = nil
	return .c.error()
}

// Busy determines if a prepared statement has been reset.
//
// https://sqlite.org/c3ref/stmt_busy.html
func ( *Stmt) () bool {
	 := res_t(.c.call("sqlite3_stmt_busy", stk_t(.handle)))
	return  != 0
}

// Step evaluates the SQL statement.
// If the SQL statement being executed returns any data,
// then true is returned each time a new row of data is ready for processing by the caller.
// The values may be accessed using the Column access functions.
// Step is called again to retrieve the next row of data.
// If an error has occurred, Step returns false;
// call [Stmt.Err] or [Stmt.Reset] to get the error.
//
// https://sqlite.org/c3ref/step.html
func ( *Stmt) () bool {
	if .c.interrupt.Err() != nil {
		.err = INTERRUPT
		return false
	}

	 := res_t(.c.call("sqlite3_step", stk_t(.handle)))
	switch  {
	case _ROW:
		.err = nil
		return true
	case _DONE:
		.err = nil
	default:
		.err = .c.error()
	}
	return false
}

// Err gets the last error occurred during [Stmt.Step].
// Err returns nil after [Stmt.Reset] is called.
//
// https://sqlite.org/c3ref/step.html
func ( *Stmt) () error {
	return .err
}

// Exec is a convenience function that repeatedly calls [Stmt.Step] until it returns false,
// then calls [Stmt.Reset] to reset the statement and get any error that occurred.
func ( *Stmt) () error {
	if .c.interrupt.Err() != nil {
		return INTERRUPT
	}
	 := res_t(.c.call("sqlite3_exec_go", stk_t(.handle)))
	.err = nil
	return .c.error()
}

// Status monitors the performance characteristics of prepared statements.
//
// https://sqlite.org/c3ref/stmt_status.html
func ( *Stmt) ( StmtStatus,  bool) int {
	if  > STMTSTATUS_FILTER_HIT &&  != STMTSTATUS_MEMUSED {
		return 0
	}
	var  int32
	if  {
		 = 1
	}
	 := int32(.c.call("sqlite3_stmt_status", stk_t(.handle),
		stk_t(), stk_t()))
	return int()
}

// ClearBindings resets all bindings on the prepared statement.
//
// https://sqlite.org/c3ref/clear_bindings.html
func ( *Stmt) () error {
	 := res_t(.c.call("sqlite3_clear_bindings", stk_t(.handle)))
	return .c.error()
}

// BindCount returns the number of SQL parameters in the prepared statement.
//
// https://sqlite.org/c3ref/bind_parameter_count.html
func ( *Stmt) () int {
	 := int32(.c.call("sqlite3_bind_parameter_count",
		stk_t(.handle)))
	return int()
}

// BindIndex returns the index of a parameter in the prepared statement
// given its name.
//
// https://sqlite.org/c3ref/bind_parameter_index.html
func ( *Stmt) ( string) int {
	defer .c.arena.mark()()
	 := .c.arena.string()
	 := int32(.c.call("sqlite3_bind_parameter_index",
		stk_t(.handle), stk_t()))
	return int()
}

// BindName returns the name of a parameter in the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_parameter_name.html
func ( *Stmt) ( int) string {
	 := ptr_t(.c.call("sqlite3_bind_parameter_name",
		stk_t(.handle), stk_t()))
	if  == 0 {
		return ""
	}
	return util.ReadString(.c.mod, , _MAX_NAME)
}

// BindBool binds a bool to the prepared statement.
// The leftmost SQL parameter has an index of 1.
// SQLite does not have a separate boolean storage class.
// Instead, boolean values are stored as integers 0 (false) and 1 (true).
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  bool) error {
	var  int64
	if  {
		 = 1
	}
	return .BindInt64(, )
}

// BindInt binds an int to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  int) error {
	return .BindInt64(, int64())
}

// BindInt64 binds an int64 to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  int64) error {
	 := res_t(.c.call("sqlite3_bind_int64",
		stk_t(.handle), stk_t(), stk_t()))
	return .c.error()
}

// BindFloat binds a float64 to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  float64) error {
	 := res_t(.c.call("sqlite3_bind_double",
		stk_t(.handle), stk_t(),
		stk_t(math.Float64bits())))
	return .c.error()
}

// BindText binds a string to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  string) error {
	if len() > _MAX_LENGTH {
		return TOOBIG
	}
	 := .c.newString()
	 := res_t(.c.call("sqlite3_bind_text_go",
		stk_t(.handle), stk_t(),
		stk_t(), stk_t(len())))
	return .c.error()
}

// BindRawText binds a []byte to the prepared statement as text.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  []byte) error {
	if len() > _MAX_LENGTH {
		return TOOBIG
	}
	if len() == 0 {
		return .BindText(, "")
	}
	 := .c.newBytes()
	 := res_t(.c.call("sqlite3_bind_text_go",
		stk_t(.handle), stk_t(),
		stk_t(), stk_t(len())))
	return .c.error()
}

// BindBlob binds a []byte to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  []byte) error {
	if len() > _MAX_LENGTH {
		return TOOBIG
	}
	if len() == 0 {
		return .BindZeroBlob(, 0)
	}
	 := .c.newBytes()
	 := res_t(.c.call("sqlite3_bind_blob_go",
		stk_t(.handle), stk_t(),
		stk_t(), stk_t(len())))
	return .c.error()
}

// BindZeroBlob binds a zero-filled, length n BLOB to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  int64) error {
	 := res_t(.c.call("sqlite3_bind_zeroblob64",
		stk_t(.handle), stk_t(), stk_t()))
	return .c.error()
}

// BindNull binds a NULL to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int) error {
	 := res_t(.c.call("sqlite3_bind_null",
		stk_t(.handle), stk_t()))
	return .c.error()
}

// BindTime binds a [time.Time] to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  time.Time,  TimeFormat) error {
	switch  {
	case TimeFormatDefault, TimeFormatAuto, time.RFC3339Nano:
		return .bindRFC3339Nano(, )
	}
	switch v := .Encode().(type) {
	case string:
		return .BindText(, )
	case int64:
		return .BindInt64(, )
	case float64:
		return .BindFloat(, )
	default:
		panic(util.AssertErr())
	}
}

func ( *Stmt) ( int,  time.Time) error {
	const  = int64(len(time.RFC3339Nano)) + 5

	 := .c.new()
	 := util.View(.c.mod, , )
	 = .AppendFormat([:0], time.RFC3339Nano)

	 := res_t(.c.call("sqlite3_bind_text_go",
		stk_t(.handle), stk_t(),
		stk_t(), stk_t(len())))
	return .c.error()
}

// BindPointer binds a NULL to the prepared statement, just like [Stmt.BindNull],
// but it also associates ptr with that NULL value such that it can be retrieved
// within an application-defined SQL function using [Value.Pointer].
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  any) error {
	 := util.AddHandle(.c.ctx, )
	 := res_t(.c.call("sqlite3_bind_pointer_go",
		stk_t(.handle), stk_t(), stk_t()))
	return .c.error()
}

// BindValue binds a copy of value to the prepared statement.
// The leftmost SQL parameter has an index of 1.
//
// https://sqlite.org/c3ref/bind_blob.html
func ( *Stmt) ( int,  Value) error {
	if .c != .c {
		return MISUSE
	}
	 := res_t(.c.call("sqlite3_bind_value",
		stk_t(.handle), stk_t(), stk_t(.handle)))
	return .c.error()
}

// DataCount resets the number of columns in a result set.
//
// https://sqlite.org/c3ref/data_count.html
func ( *Stmt) () int {
	 := int32(.c.call("sqlite3_data_count",
		stk_t(.handle)))
	return int()
}

// ColumnCount returns the number of columns in a result set.
//
// https://sqlite.org/c3ref/column_count.html
func ( *Stmt) () int {
	 := int32(.c.call("sqlite3_column_count",
		stk_t(.handle)))
	return int()
}

// ColumnName returns the name of the result column.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_name.html
func ( *Stmt) ( int) string {
	 := ptr_t(.c.call("sqlite3_column_name",
		stk_t(.handle), stk_t()))
	if  == 0 {
		panic(util.OOMErr)
	}
	return util.ReadString(.c.mod, , _MAX_NAME)
}

// ColumnType returns the initial [Datatype] of the result column.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int) Datatype {
	return Datatype(.c.call("sqlite3_column_type",
		stk_t(.handle), stk_t()))
}

// ColumnDeclType returns the declared datatype of the result column.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_decltype.html
func ( *Stmt) ( int) string {
	 := ptr_t(.c.call("sqlite3_column_decltype",
		stk_t(.handle), stk_t()))
	if  == 0 {
		return ""
	}
	return util.ReadString(.c.mod, , _MAX_NAME)
}

// ColumnDatabaseName returns the name of the database
// that is the origin of a particular result column.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_database_name.html
func ( *Stmt) ( int) string {
	 := ptr_t(.c.call("sqlite3_column_database_name",
		stk_t(.handle), stk_t()))
	if  == 0 {
		return ""
	}
	return util.ReadString(.c.mod, , _MAX_NAME)
}

// ColumnTableName returns the name of the table
// that is the origin of a particular result column.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_database_name.html
func ( *Stmt) ( int) string {
	 := ptr_t(.c.call("sqlite3_column_table_name",
		stk_t(.handle), stk_t()))
	if  == 0 {
		return ""
	}
	return util.ReadString(.c.mod, , _MAX_NAME)
}

// ColumnOriginName returns the name of the table column
// that is the origin of a particular result column.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_database_name.html
func ( *Stmt) ( int) string {
	 := ptr_t(.c.call("sqlite3_column_origin_name",
		stk_t(.handle), stk_t()))
	if  == 0 {
		return ""
	}
	return util.ReadString(.c.mod, , _MAX_NAME)
}

// ColumnBool returns the value of the result column as a bool.
// The leftmost column of the result set has the index 0.
// SQLite does not have a separate boolean storage class.
// Instead, boolean values are retrieved as numbers,
// with 0 converted to false and any other value to true.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int) bool {
	return .ColumnFloat() != 0
}

// ColumnInt returns the value of the result column as an int.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int) int {
	return int(.ColumnInt64())
}

// ColumnInt64 returns the value of the result column as an int64.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int) int64 {
	return int64(.c.call("sqlite3_column_int64",
		stk_t(.handle), stk_t()))
}

// ColumnFloat returns the value of the result column as a float64.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int) float64 {
	 := uint64(.c.call("sqlite3_column_double",
		stk_t(.handle), stk_t()))
	return math.Float64frombits()
}

// ColumnTime returns the value of the result column as a [time.Time].
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int,  TimeFormat) time.Time {
	var  any
	switch .ColumnType() {
	case INTEGER:
		 = .ColumnInt64()
	case FLOAT:
		 = .ColumnFloat()
	case TEXT, BLOB:
		 = .ColumnText()
	case NULL:
		return time.Time{}
	default:
		panic(util.AssertErr())
	}
	,  := .Decode()
	if  != nil {
		.err = 
	}
	return 
}

// ColumnText returns the value of the result column as a string.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int) string {
	return string(.ColumnRawText())
}

// ColumnBlob appends to buf and returns
// the value of the result column as a []byte.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int,  []byte) []byte {
	return append(, .ColumnRawBlob()...)
}

// ColumnRawText returns the value of the result column as a []byte.
// The []byte is owned by SQLite and may be invalidated by
// subsequent calls to [Stmt] methods.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int) []byte {
	 := ptr_t(.c.call("sqlite3_column_text",
		stk_t(.handle), stk_t()))
	return .columnRawBytes(, , 1)
}

// ColumnRawBlob returns the value of the result column as a []byte.
// The []byte is owned by SQLite and may be invalidated by
// subsequent calls to [Stmt] methods.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int) []byte {
	 := ptr_t(.c.call("sqlite3_column_blob",
		stk_t(.handle), stk_t()))
	return .columnRawBytes(, , 0)
}

func ( *Stmt) ( int,  ptr_t,  int32) []byte {
	if  == 0 {
		 := res_t(.c.call("sqlite3_errcode", stk_t(.c.handle)))
		if  != _ROW &&  != _DONE {
			.err = .c.error()
		}
		return nil
	}

	 := int32(.c.call("sqlite3_column_bytes",
		stk_t(.handle), stk_t()))
	return util.View(.c.mod, , int64(+))[:]
}

// ColumnValue returns the unprotected value of the result column.
// The leftmost column of the result set has the index 0.
//
// https://sqlite.org/c3ref/column_blob.html
func ( *Stmt) ( int) Value {
	 := ptr_t(.c.call("sqlite3_column_value",
		stk_t(.handle), stk_t()))
	return Value{
		c:      .c,
		handle: ,
	}
}

// Columns populates result columns into the provided slice.
// The slice must have [Stmt.ColumnCount] length.
//
// [INTEGER] columns will be retrieved as int64 values,
// [FLOAT] as float64, [NULL] as nil,
// [TEXT] as string, and [BLOB] as []byte.
func ( *Stmt) ( ...any) error {
	defer .c.arena.mark()()
	, ,  := .columns(int64(len()))
	if  != nil {
		return 
	}

	// Avoid bounds checks on types below.
	if len() != len() {
		panic(util.AssertErr())
	}

	for  := range  {
		switch [] {
		case byte(INTEGER):
			[] = util.Read64[int64](.c.mod, )
		case byte(FLOAT):
			[] = util.ReadFloat64(.c.mod, )
		case byte(NULL):
			[] = nil
		case byte(TEXT):
			 := util.Read32[int32](.c.mod, +4)
			if  != 0 {
				 := util.Read32[ptr_t](.c.mod, )
				 := util.View(.c.mod, , int64())
				[] = string()
			} else {
				[] = ""
			}
		case byte(BLOB):
			 := util.Read32[int32](.c.mod, +4)
			if  != 0 {
				 := util.Read32[ptr_t](.c.mod, )
				 := util.View(.c.mod, , int64())
				,  := [].([]byte)
				[] = append([:0], ...)
			} else {
				[], _ = [].([]byte)
			}
		}
		 += 8
	}
	return nil
}

// ColumnsRaw populates result columns into the provided slice.
// The slice must have [Stmt.ColumnCount] length.
//
// [INTEGER] columns will be retrieved as int64 values,
// [FLOAT] as float64, [NULL] as nil,
// [TEXT] and [BLOB] as []byte.
// Any []byte are owned by SQLite and may be invalidated by
// subsequent calls to [Stmt] methods.
func ( *Stmt) ( ...any) error {
	defer .c.arena.mark()()
	, ,  := .columns(int64(len()))
	if  != nil {
		return 
	}

	// Avoid bounds checks on types below.
	if len() != len() {
		panic(util.AssertErr())
	}

	for  := range  {
		switch [] {
		case byte(INTEGER):
			[] = util.Read64[int64](.c.mod, )
		case byte(FLOAT):
			[] = util.ReadFloat64(.c.mod, )
		case byte(NULL):
			[] = nil
		default:
			 := util.Read32[int32](.c.mod, +4)
			if  == 0 && [] == byte(BLOB) {
				[] = []byte{}
			} else {
				 := 
				if [] == byte(TEXT) {
					++
				}
				 := util.Read32[ptr_t](.c.mod, )
				 := util.View(.c.mod, , int64())[:]
				[] = 
			}
		}
		 += 8
	}
	return nil
}

func ( *Stmt) ( int64) ([]byte, ptr_t, error) {
	 := .c.arena.new()
	 := .c.arena.new( * 8)

	 := res_t(.c.call("sqlite3_columns_go",
		stk_t(.handle), stk_t(), stk_t(), stk_t()))
	if  == res_t(MISUSE) {
		return nil, 0, MISUSE
	}
	if  := .c.error();  != nil {
		return nil, 0, 
	}

	return util.View(.c.mod, , ), , nil
}