// Copyright 2017 The Sqlite Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:generate go run generator.go
//go:generate go fmt ./...

package sqlite // import "modernc.org/sqlite"

import (
	
	
	
	
	
	
	
	
	
	
	

	
	
	sqlite3 
)

var (
	_ driver.Conn   = (*conn)(nil)
	_ driver.Driver = (*Driver)(nil)
	//lint:ignore SA1019 TODO implement ExecerContext
	_ driver.Execer = (*conn)(nil)
	//lint:ignore SA1019 TODO implement QueryerContext
	_ driver.Queryer                        = (*conn)(nil)
	_ driver.Result                         = (*result)(nil)
	_ driver.Rows                           = (*rows)(nil)
	_ driver.RowsColumnTypeDatabaseTypeName = (*rows)(nil)
	_ driver.RowsColumnTypeLength           = (*rows)(nil)
	_ driver.RowsColumnTypeNullable         = (*rows)(nil)
	_ driver.RowsColumnTypePrecisionScale   = (*rows)(nil)
	_ driver.RowsColumnTypeScanType         = (*rows)(nil)
	_ driver.Stmt                           = (*stmt)(nil)
	_ driver.Tx                             = (*tx)(nil)
	_ error                                 = (*Error)(nil)
)

const (
	driverName              = "sqlite"
	ptrSize                 = unsafe.Sizeof(uintptr(0))
	sqliteLockedSharedcache = sqlite3.SQLITE_LOCKED | (1 << 8)
)

// Error represents sqlite library error code.
type Error struct {
	msg  string
	code int
}

// Error implements error.
func ( *Error) () string { return .msg }

// Code returns the sqlite result code for this error.
func ( *Error) () int { return .code }

var (
	// ErrorCodeString maps Error.Code() to its string representation.
	ErrorCodeString = map[int]string{
		sqlite3.SQLITE_ABORT:             "Callback routine requested an abort (SQLITE_ABORT)",
		sqlite3.SQLITE_AUTH:              "Authorization denied (SQLITE_AUTH)",
		sqlite3.SQLITE_BUSY:              "The database file is locked (SQLITE_BUSY)",
		sqlite3.SQLITE_CANTOPEN:          "Unable to open the database file (SQLITE_CANTOPEN)",
		sqlite3.SQLITE_CONSTRAINT:        "Abort due to constraint violation (SQLITE_CONSTRAINT)",
		sqlite3.SQLITE_CORRUPT:           "The database disk image is malformed (SQLITE_CORRUPT)",
		sqlite3.SQLITE_DONE:              "sqlite3_step() has finished executing (SQLITE_DONE)",
		sqlite3.SQLITE_EMPTY:             "Internal use only (SQLITE_EMPTY)",
		sqlite3.SQLITE_ERROR:             "Generic error (SQLITE_ERROR)",
		sqlite3.SQLITE_FORMAT:            "Not used (SQLITE_FORMAT)",
		sqlite3.SQLITE_FULL:              "Insertion failed because database is full (SQLITE_FULL)",
		sqlite3.SQLITE_INTERNAL:          "Internal logic error in SQLite (SQLITE_INTERNAL)",
		sqlite3.SQLITE_INTERRUPT:         "Operation terminated by sqlite3_interrupt()(SQLITE_INTERRUPT)",
		sqlite3.SQLITE_IOERR | (1 << 8):  "(SQLITE_IOERR_READ)",
		sqlite3.SQLITE_IOERR | (10 << 8): "(SQLITE_IOERR_DELETE)",
		sqlite3.SQLITE_IOERR | (11 << 8): "(SQLITE_IOERR_BLOCKED)",
		sqlite3.SQLITE_IOERR | (12 << 8): "(SQLITE_IOERR_NOMEM)",
		sqlite3.SQLITE_IOERR | (13 << 8): "(SQLITE_IOERR_ACCESS)",
		sqlite3.SQLITE_IOERR | (14 << 8): "(SQLITE_IOERR_CHECKRESERVEDLOCK)",
		sqlite3.SQLITE_IOERR | (15 << 8): "(SQLITE_IOERR_LOCK)",
		sqlite3.SQLITE_IOERR | (16 << 8): "(SQLITE_IOERR_CLOSE)",
		sqlite3.SQLITE_IOERR | (17 << 8): "(SQLITE_IOERR_DIR_CLOSE)",
		sqlite3.SQLITE_IOERR | (2 << 8):  "(SQLITE_IOERR_SHORT_READ)",
		sqlite3.SQLITE_IOERR | (3 << 8):  "(SQLITE_IOERR_WRITE)",
		sqlite3.SQLITE_IOERR | (4 << 8):  "(SQLITE_IOERR_FSYNC)",
		sqlite3.SQLITE_IOERR | (5 << 8):  "(SQLITE_IOERR_DIR_FSYNC)",
		sqlite3.SQLITE_IOERR | (6 << 8):  "(SQLITE_IOERR_TRUNCATE)",
		sqlite3.SQLITE_IOERR | (7 << 8):  "(SQLITE_IOERR_FSTAT)",
		sqlite3.SQLITE_IOERR | (8 << 8):  "(SQLITE_IOERR_UNLOCK)",
		sqlite3.SQLITE_IOERR | (9 << 8):  "(SQLITE_IOERR_RDLOCK)",
		sqlite3.SQLITE_IOERR:             "Some kind of disk I/O error occurred (SQLITE_IOERR)",
		sqlite3.SQLITE_LOCKED | (1 << 8): "(SQLITE_LOCKED_SHAREDCACHE)",
		sqlite3.SQLITE_LOCKED:            "A table in the database is locked (SQLITE_LOCKED)",
		sqlite3.SQLITE_MISMATCH:          "Data type mismatch (SQLITE_MISMATCH)",
		sqlite3.SQLITE_MISUSE:            "Library used incorrectly (SQLITE_MISUSE)",
		sqlite3.SQLITE_NOLFS:             "Uses OS features not supported on host (SQLITE_NOLFS)",
		sqlite3.SQLITE_NOMEM:             "A malloc() failed (SQLITE_NOMEM)",
		sqlite3.SQLITE_NOTADB:            "File opened that is not a database file (SQLITE_NOTADB)",
		sqlite3.SQLITE_NOTFOUND:          "Unknown opcode in sqlite3_file_control() (SQLITE_NOTFOUND)",
		sqlite3.SQLITE_NOTICE:            "Notifications from sqlite3_log() (SQLITE_NOTICE)",
		sqlite3.SQLITE_PERM:              "Access permission denied (SQLITE_PERM)",
		sqlite3.SQLITE_PROTOCOL:          "Database lock protocol error (SQLITE_PROTOCOL)",
		sqlite3.SQLITE_RANGE:             "2nd parameter to sqlite3_bind out of range (SQLITE_RANGE)",
		sqlite3.SQLITE_READONLY:          "Attempt to write a readonly database (SQLITE_READONLY)",
		sqlite3.SQLITE_ROW:               "sqlite3_step() has another row ready (SQLITE_ROW)",
		sqlite3.SQLITE_SCHEMA:            "The database schema changed (SQLITE_SCHEMA)",
		sqlite3.SQLITE_TOOBIG:            "String or BLOB exceeds size limit (SQLITE_TOOBIG)",
		sqlite3.SQLITE_WARNING:           "Warnings from sqlite3_log() (SQLITE_WARNING)",
	}
)

func () {
	sql.Register(driverName, newDriver())
}

type result struct {
	lastInsertID int64
	rowsAffected int
}

func ( *conn) ( *result,  error) {
	 := &result{}
	if .rowsAffected,  = .changes();  != nil {
		return nil, 
	}

	if .lastInsertID,  = .lastInsertRowID();  != nil {
		return nil, 
	}

	return , nil
}

// LastInsertId returns the database's auto-generated ID after, for example, an
// INSERT into a table with primary key.
func ( *result) () (int64, error) {
	if  == nil {
		return 0, nil
	}

	return .lastInsertID, nil
}

// RowsAffected returns the number of rows affected by the query.
func ( *result) () (int64, error) {
	if  == nil {
		return 0, nil
	}

	return int64(.rowsAffected), nil
}

type rows struct {
	allocs  []uintptr
	c       *conn
	columns []string
	pstmt   uintptr

	doStep bool
	empty  bool
}

func ( *conn,  uintptr,  []uintptr,  bool) ( *rows,  error) {
	 = &rows{c: , pstmt: , allocs: , empty: }

	defer func() {
		if  != nil {
			.Close()
			 = nil
		}
	}()

	,  := .columnCount()
	if  != nil {
		return nil, 
	}

	.columns = make([]string, )
	for  := range .columns {
		if .columns[],  = .c.columnName(, );  != nil {
			return nil, 
		}
	}

	return , nil
}

// Close closes the rows iterator.
func ( *rows) () ( error) {
	for ,  := range .allocs {
		.c.free()
	}
	.allocs = nil
	return .c.finalize(.pstmt)
}

// Columns returns the names of the columns. The number of columns of the
// result is inferred from the length of the slice. If a particular column name
// isn't known, an empty string should be returned for that entry.
func ( *rows) () ( []string) {
	return .columns
}

// Next is called to populate the next row of data into the provided slice. The
// provided slice will be the same size as the Columns() are wide.
//
// Next should return io.EOF when there are no more rows.
func ( *rows) ( []driver.Value) ( error) {
	if .empty {
		return io.EOF
	}

	 := sqlite3.SQLITE_ROW
	if .doStep {
		if ,  = .c.step(.pstmt);  != nil {
			return 
		}
	}

	.doStep = true
	switch  {
	case sqlite3.SQLITE_ROW:
		if ,  := len(), len(.columns);  !=  {
			return fmt.Errorf("sqlite: Next: have %v destination values, expected %v", , )
		}

		for  := range  {
			,  := .c.columnType(.pstmt, )
			if  != nil {
				return 
			}

			switch  {
			case sqlite3.SQLITE_INTEGER:
				,  := .c.columnInt64(.pstmt, )
				if  != nil {
					return 
				}

				[] = 
			case sqlite3.SQLITE_FLOAT:
				,  := .c.columnDouble(.pstmt, )
				if  != nil {
					return 
				}

				[] = 
			case sqlite3.SQLITE_TEXT:
				,  := .c.columnText(.pstmt, )
				if  != nil {
					return 
				}

				switch .ColumnTypeDatabaseTypeName() {
				case "DATE", "DATETIME", "TIMESTAMP":
					[], _ = .c.parseTime()
				default:
					[] = 
				}
			case sqlite3.SQLITE_BLOB:
				,  := .c.columnBlob(.pstmt, )
				if  != nil {
					return 
				}

				[] = 
			case sqlite3.SQLITE_NULL:
				[] = nil
			default:
				return fmt.Errorf("internal error: rc %d", )
			}
		}
		return nil
	case sqlite3.SQLITE_DONE:
		return io.EOF
	default:
		return .c.errstr(int32())
	}
}

// Inspired by mattn/go-sqlite3: https://github.com/mattn/go-sqlite3/blob/ab91e934/sqlite3.go#L210-L226
//
// These time.Parse formats handle formats 1 through 7 listed at https://www.sqlite.org/lang_datefunc.html.
var parseTimeFormats = []string{
	"2006-01-02 15:04:05.999999999-07:00",
	"2006-01-02T15:04:05.999999999-07:00",
	"2006-01-02 15:04:05.999999999",
	"2006-01-02T15:04:05.999999999",
	"2006-01-02 15:04",
	"2006-01-02T15:04",
	"2006-01-02",
}

// Attempt to parse s as a time. Return (s, false) if s is not
// recognized as a valid time encoding.
func ( *conn) ( string) (interface{}, bool) {
	if ,  := .parseTimeString(, strings.Index(, "m="));  {
		return , true
	}

	 := strings.TrimSuffix(, "Z")

	for ,  := range parseTimeFormats {
		,  := time.Parse(, )
		if  == nil {
			return , true
		}
	}

	return , false
}

// Attempt to parse s as a time string produced by t.String().  If x > 0 it's
// the index of substring "m=" within s.  Return (s, false) if s is
// not recognized as a valid time encoding.
func ( *conn) ( string,  int) (interface{}, bool) {
	 := 
	if  > 0 {
		 = [:] // "2006-01-02 15:04:05.999999999 -0700 MST m=+9999" -> "2006-01-02 15:04:05.999999999 -0700 MST "
	}
	 = strings.TrimSpace()
	if ,  := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", );  == nil {
		return , true
	}

	return , false
}

// RowsColumnTypeDatabaseTypeName may be implemented by Rows. It should return
// the database system type name without the length. Type names should be
// uppercase. Examples of returned types: "VARCHAR", "NVARCHAR", "VARCHAR2",
// "CHAR", "TEXT", "DECIMAL", "SMALLINT", "INT", "BIGINT", "BOOL", "[]BIGINT",
// "JSONB", "XML", "TIMESTAMP".
func ( *rows) ( int) string {
	return strings.ToUpper(.c.columnDeclType(.pstmt, ))
}

// RowsColumnTypeLength may be implemented by Rows. It should return the length
// of the column type if the column is a variable length type. If the column is
// not a variable length type ok should return false. If length is not limited
// other than system limits, it should return math.MaxInt64. The following are
// examples of returned values for various types:
//
//	TEXT          (math.MaxInt64, true)
//	varchar(10)   (10, true)
//	nvarchar(10)  (10, true)
//	decimal       (0, false)
//	int           (0, false)
//	bytea(30)     (30, true)
func ( *rows) ( int) ( int64,  bool) {
	,  := .c.columnType(.pstmt, )
	if  != nil {
		return 0, false
	}

	switch  {
	case sqlite3.SQLITE_INTEGER:
		return 0, false
	case sqlite3.SQLITE_FLOAT:
		return 0, false
	case sqlite3.SQLITE_TEXT:
		return math.MaxInt64, true
	case sqlite3.SQLITE_BLOB:
		return math.MaxInt64, true
	case sqlite3.SQLITE_NULL:
		return 0, false
	default:
		return 0, false
	}
}

// RowsColumnTypeNullable may be implemented by Rows. The nullable value should
// be true if it is known the column may be null, or false if the column is
// known to be not nullable. If the column nullability is unknown, ok should be
// false.
func ( *rows) ( int) (,  bool) {
	return true, true
}

// RowsColumnTypePrecisionScale may be implemented by Rows. It should return
// the precision and scale for decimal types. If not applicable, ok should be
// false. The following are examples of returned values for various types:
//
//	decimal(38, 4)    (38, 4, true)
//	int               (0, 0, false)
//	decimal           (math.MaxInt64, math.MaxInt64, true)
func ( *rows) ( int) (,  int64,  bool) {
	return 0, 0, false
}

// RowsColumnTypeScanType may be implemented by Rows. It should return the
// value type that can be used to scan types into. For example, the database
// column type "bigint" this should return "reflect.TypeOf(int64(0))".
func ( *rows) ( int) reflect.Type {
	,  := .c.columnType(.pstmt, )
	if  != nil {
		return reflect.TypeOf("")
	}

	switch  {
	case sqlite3.SQLITE_INTEGER:
		switch strings.ToLower(.c.columnDeclType(.pstmt, )) {
		case "boolean":
			return reflect.TypeOf(false)
		case "date", "datetime", "time", "timestamp":
			return reflect.TypeOf(time.Time{})
		default:
			return reflect.TypeOf(int64(0))
		}
	case sqlite3.SQLITE_FLOAT:
		return reflect.TypeOf(float64(0))
	case sqlite3.SQLITE_TEXT:
		return reflect.TypeOf("")
	case sqlite3.SQLITE_BLOB:
		return reflect.SliceOf(reflect.TypeOf([]byte{}))
	case sqlite3.SQLITE_NULL:
		return reflect.TypeOf(nil)
	default:
		return reflect.TypeOf("")
	}
}

type stmt struct {
	c    *conn
	psql uintptr
}

func ( *conn,  string) (*stmt, error) {
	,  := libc.CString()
	if  != nil {
		return nil, 
	}
	 := stmt{c: , psql: }

	return &, nil
}

// Close closes the statement.
//
// As of Go 1.1, a Stmt will not be closed if it's in use by any queries.
func ( *stmt) () ( error) {
	.c.free(.psql)
	.psql = 0
	return nil
}

// Exec executes a query that doesn't return rows, such as an INSERT or UPDATE.
//
//
// Deprecated: Drivers should implement StmtExecContext instead (or
// additionally).
func ( *stmt) ( []driver.Value) (driver.Result, error) { //TODO StmtExecContext
	return .exec(context.Background(), toNamedValues())
}

// toNamedValues converts []driver.Value to []driver.NamedValue
func ( []driver.Value) ( []driver.NamedValue) {
	 = make([]driver.NamedValue, len())
	for ,  := range  {
		[] = driver.NamedValue{Value: , Ordinal:  + 1}
	}
	return 
}

func ( *stmt) ( context.Context,  []driver.NamedValue) ( driver.Result,  error) {
	var  uintptr
	 := false
	if  != nil && .Done() != nil {
		 := make(chan struct{})

		go func() {
			select {
			case <-.Done():
				 = true
				.c.interrupt(.c.db)
			case <-:
			}
		}()

		defer func() {
			close()
		}()
	}

	for  := .psql; *(*byte)(unsafe.Pointer()) != 0 && !; {
		if ,  = .c.prepareV2(&);  != nil {
			return nil, 
		}

		if  == 0 {
			continue
		}
		 = func() ( error) {
			,  := .c.bindParameterCount()
			if  != nil {
				return 
			}

			if  != 0 {
				,  := .c.bind(, , )
				if  != nil {
					return 
				}

				if len() != 0 {
					defer func() {
						for ,  := range  {
							.c.free()
						}
					}()
				}
			}

			,  := .c.step()
			if  != nil {
				return 
			}

			switch  & 0xff {
			case sqlite3.SQLITE_DONE, sqlite3.SQLITE_ROW:
				// nop
			default:
				return .c.errstr(int32())
			}

			return nil
		}()

		if  := .c.finalize();  != nil &&  == nil {
			 = 
		}

		if  != nil {
			return nil, 
		}
	}
	return newResult(.c)
}

// NumInput returns the number of placeholder parameters.
//
// If NumInput returns >= 0, the sql package will sanity check argument counts
// from callers and return errors to the caller before the statement's Exec or
// Query methods are called.
//
// NumInput may also return -1, if the driver doesn't know its number of
// placeholders. In that case, the sql package will not sanity check Exec or
// Query argument counts.
func ( *stmt) () ( int) {
	return -1
}

// Query executes a query that may return rows, such as a
// SELECT.
//
// Deprecated: Drivers should implement StmtQueryContext instead (or
// additionally).
func ( *stmt) ( []driver.Value) (driver.Rows, error) { //TODO StmtQueryContext
	return .query(context.Background(), toNamedValues())
}

func ( *stmt) ( context.Context,  []driver.NamedValue) ( driver.Rows,  error) {
	var  uintptr

	 := false
	if  != nil && .Done() != nil {
		 := make(chan struct{})

		go func() {
			select {
			case <-.Done():
				 = true
				.c.interrupt(.c.db)
			case <-:
			}
		}()

		defer func() {
			close()
		}()
	}

	var  []uintptr
	for  := .psql; *(*byte)(unsafe.Pointer()) != 0 && !; {
		if ,  = .c.prepareV2(&);  != nil {
			return nil, 
		}

		if  == 0 {
			continue
		}

		 = func() ( error) {
			,  := .c.bindParameterCount()
			if  != nil {
				return 
			}

			if  != 0 {
				if ,  = .c.bind(, , );  != nil {
					return 
				}
			}

			,  := .c.step()
			if  != nil {
				return 
			}

			switch  & 0xff {
			case sqlite3.SQLITE_ROW:
				if  != nil {
					.Close()
				}
				if ,  = newRows(.c, , , false);  != nil {
					return 
				}

				 = 0
				return nil
			case sqlite3.SQLITE_DONE:
				if  == nil {
					if ,  = newRows(.c, , , true);  != nil {
						return 
					}
					 = 0
					return nil
				}

				// nop
			default:
				return .c.errstr(int32())
			}

			if *(*byte)(unsafe.Pointer()) == 0 {
				if  != nil {
					.Close()
				}
				if ,  = newRows(.c, , , true);  != nil {
					return 
				}

				 = 0
			}
			return nil
		}()
		if  := .c.finalize();  != nil &&  == nil {
			 = 
		}

		if  != nil {
			return nil, 
		}
	}
	return , 
}

type tx struct {
	c *conn
}

func ( *conn) (*tx, error) {
	 := &tx{c: }
	if  := .exec(context.Background(), "begin");  != nil {
		return nil, 
	}

	return , nil
}

// Commit implements driver.Tx.
func ( *tx) () ( error) {
	return .exec(context.Background(), "commit")
}

// Rollback implements driver.Tx.
func ( *tx) () ( error) {
	return .exec(context.Background(), "rollback")
}

func ( *tx) ( context.Context,  string) ( error) {
	,  := libc.CString()
	if  != nil {
		return 
	}

	defer .c.free()
	//TODO use t.conn.ExecContext() instead

	if  != nil && .Done() != nil {
		 := make(chan struct{})

		go func() {
			select {
			case <-.Done():
				.c.interrupt(.c.db)
			case <-:
			}
		}()

		defer func() {
			close()
		}()
	}

	if  := sqlite3.Xsqlite3_exec(.c.tls, .c.db, , 0, 0, 0);  != sqlite3.SQLITE_OK {
		return .c.errstr()
	}

	return nil
}

type conn struct {
	db  uintptr // *sqlite3.Xsqlite3
	tls *libc.TLS
}

func ( string) (*conn, error) {
	 := &conn{tls: libc.NewTLS()}
	,  := .openV2(
		,
		sqlite3.SQLITE_OPEN_READWRITE|sqlite3.SQLITE_OPEN_CREATE|
			sqlite3.SQLITE_OPEN_FULLMUTEX|
			sqlite3.SQLITE_OPEN_URI,
	)
	if  != nil {
		return nil, 
	}

	.db = 
	if  = .extendedResultCodes(true);  != nil {
		.Close()
		return nil, 
	}

	return , nil
}

// const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
func ( *conn) ( uintptr,  int) ( []byte,  error) {
	 := sqlite3.Xsqlite3_column_blob(.tls, , int32())
	,  := .columnBytes(, )
	if  != nil {
		return nil, 
	}

	if  == 0 ||  == 0 {
		return nil, nil
	}

	 = make([]byte, )
	copy(, (*libc.RawMem)(unsafe.Pointer())[::])
	return , nil
}

// int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
func ( *conn) ( uintptr,  int) ( int,  error) {
	 := sqlite3.Xsqlite3_column_bytes(.tls, , int32())
	return int(), nil
}

// const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
func ( *conn) ( uintptr,  int) ( string,  error) {
	 := sqlite3.Xsqlite3_column_text(.tls, , int32())
	,  := .columnBytes(, )
	if  != nil {
		return "", 
	}

	if  == 0 ||  == 0 {
		return "", nil
	}

	 := make([]byte, )
	copy(, (*libc.RawMem)(unsafe.Pointer())[::])
	return string(), nil
}

// double sqlite3_column_double(sqlite3_stmt*, int iCol);
func ( *conn) ( uintptr,  int) ( float64,  error) {
	 = sqlite3.Xsqlite3_column_double(.tls, , int32())
	return , nil
}

// sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
func ( *conn) ( uintptr,  int) ( int64,  error) {
	 = sqlite3.Xsqlite3_column_int64(.tls, , int32())
	return , nil
}

// int sqlite3_column_type(sqlite3_stmt*, int iCol);
func ( *conn) ( uintptr,  int) ( int,  error) {
	 := sqlite3.Xsqlite3_column_type(.tls, , int32())
	return int(), nil
}

// const char *sqlite3_column_decltype(sqlite3_stmt*,int);
func ( *conn) ( uintptr,  int) string {
	return libc.GoString(sqlite3.Xsqlite3_column_decltype(.tls, , int32()))
}

// const char *sqlite3_column_name(sqlite3_stmt*, int N);
func ( *conn) ( uintptr,  int) (string, error) {
	 := sqlite3.Xsqlite3_column_name(.tls, , int32())
	return libc.GoString(), nil
}

// int sqlite3_column_count(sqlite3_stmt *pStmt);
func ( *conn) ( uintptr) ( int,  error) {
	 := sqlite3.Xsqlite3_column_count(.tls, )
	return int(), nil
}

// sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
func ( *conn) () ( int64,  error) {
	return sqlite3.Xsqlite3_last_insert_rowid(.tls, .db), nil
}

// int sqlite3_changes(sqlite3*);
func ( *conn) () (int, error) {
	 := sqlite3.Xsqlite3_changes(.tls, .db)
	return int(), nil
}

// int sqlite3_step(sqlite3_stmt*);
func ( *conn) ( uintptr) (int, error) {
	for {
		switch  := sqlite3.Xsqlite3_step(.tls, );  {
		case sqliteLockedSharedcache, sqlite3.SQLITE_BUSY:
			if  := .retry();  != nil {
				return sqlite3.SQLITE_LOCKED, 
			}
		default:
			return int(), nil
		}
	}
}

func ( *conn) ( uintptr) error {
	 := mutexAlloc(.tls)
	(*mutex)(unsafe.Pointer()).Lock()
	 := sqlite3.Xsqlite3_unlock_notify(
		.tls,
		.db,
		*(*uintptr)(unsafe.Pointer(&struct {
			 func(*libc.TLS, uintptr, int32)
		}{unlockNotify})),
		,
	)
	if  == sqlite3.SQLITE_LOCKED { // Deadlock, see https://www.sqlite.org/c3ref/unlock_notify.html
		(*mutex)(unsafe.Pointer()).Unlock()
		mutexFree(.tls, )
		return .errstr()
	}

	(*mutex)(unsafe.Pointer()).Lock()
	(*mutex)(unsafe.Pointer()).Unlock()
	mutexFree(.tls, )
	if  != 0 {
		sqlite3.Xsqlite3_reset(.tls, )
	}
	return nil
}

func ( *libc.TLS,  uintptr,  int32) {
	for  := int32(0);  < ; ++ {
		 := *(*uintptr)(unsafe.Pointer())
		(*mutex)(unsafe.Pointer()).Unlock()
		 += ptrSize
	}
}

func ( *conn) ( uintptr,  int,  []driver.NamedValue) ( []uintptr,  error) {
	defer func() {
		if  == nil {
			return
		}

		for ,  := range  {
			.free()
		}
		 = nil
	}()

	for  := 1;  <= ; ++ {
		,  := .bindParameterName(, )
		if  != nil {
			return , 
		}

		var  bool
		var  driver.NamedValue
		for _,  = range  {
			if  != "" {
				// For ?NNN and $NNN params, match if NNN == v.Ordinal.
				//
				// Supporting this for $NNN is a special case that makes eg
				// `select $1, $2, $3 ...` work without needing to use
				// sql.Named.
				if ([0] == '?' || [0] == '$') && [1:] == strconv.Itoa(.Ordinal) {
					 = true
					break
				}

				// sqlite supports '$', '@' and ':' prefixes for string
				// identifiers and '?' for numeric, so we cannot
				// combine different prefixes with the same name
				// because `database/sql` requires variable names
				// to start with a letter
				if [1:] == .Name[:] {
					 = true
					break
				}
			} else {
				if .Ordinal ==  {
					 = true
					break
				}
			}
		}

		if ! {
			if  != "" {
				return , fmt.Errorf("missing named argument %q", [1:])
			}

			return , fmt.Errorf("missing argument with index %d", )
		}

		var  uintptr
		switch x := .Value.(type) {
		case int64:
			if  := .bindInt64(, , );  != nil {
				return , 
			}
		case float64:
			if  := .bindDouble(, , );  != nil {
				return , 
			}
		case bool:
			 := 0
			if  {
				 = 1
			}
			if  := .bindInt(, , );  != nil {
				return , 
			}
		case []byte:
			if ,  = .bindBlob(, , );  != nil {
				return , 
			}
		case string:
			if ,  = .bindText(, , );  != nil {
				return , 
			}
		case time.Time:
			if ,  = .bindText(, , .String());  != nil {
				return , 
			}
		case nil:
			if ,  = .bindNull(, );  != nil {
				return , 
			}
		default:
			return , fmt.Errorf("sqlite: invalid driver.Value type %T", )
		}
		if  != 0 {
			 = append(, )
		}
	}
	return , nil
}

// int sqlite3_bind_null(sqlite3_stmt*, int);
func ( *conn) ( uintptr,  int) (uintptr, error) {
	if  := sqlite3.Xsqlite3_bind_null(.tls, , int32());  != sqlite3.SQLITE_OK {
		return 0, .errstr()
	}

	return 0, nil
}

// int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
func ( *conn) ( uintptr,  int,  string) (uintptr, error) {
	,  := libc.CString()
	if  != nil {
		return 0, 
	}

	if  := sqlite3.Xsqlite3_bind_text(.tls, , int32(), , int32(len()), 0);  != sqlite3.SQLITE_OK {
		.free()
		return 0, .errstr()
	}

	return , nil
}

// int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
func ( *conn) ( uintptr,  int,  []byte) (uintptr, error) {
	,  := .malloc(len())
	if  != nil {
		return 0, 
	}

	if len() != 0 {
		copy((*libc.RawMem)(unsafe.Pointer())[:len():len()], )
	}
	if  := sqlite3.Xsqlite3_bind_blob(.tls, , int32(), , int32(len()), 0);  != sqlite3.SQLITE_OK {
		.free()
		return 0, .errstr()
	}

	return , nil
}

// int sqlite3_bind_int(sqlite3_stmt*, int, int);
func ( *conn) ( uintptr, ,  int) ( error) {
	if  := sqlite3.Xsqlite3_bind_int(.tls, , int32(), int32());  != sqlite3.SQLITE_OK {
		return .errstr()
	}

	return nil
}

// int sqlite3_bind_double(sqlite3_stmt*, int, double);
func ( *conn) ( uintptr,  int,  float64) ( error) {
	if  := sqlite3.Xsqlite3_bind_double(.tls, , int32(), );  != 0 {
		return .errstr()
	}

	return nil
}

// int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
func ( *conn) ( uintptr,  int,  int64) ( error) {
	if  := sqlite3.Xsqlite3_bind_int64(.tls, , int32(), );  != sqlite3.SQLITE_OK {
		return .errstr()
	}

	return nil
}

// const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
func ( *conn) ( uintptr,  int) (string, error) {
	 := sqlite3.Xsqlite3_bind_parameter_name(.tls, , int32())
	return libc.GoString(), nil
}

// int sqlite3_bind_parameter_count(sqlite3_stmt*);
func ( *conn) ( uintptr) ( int,  error) {
	 := sqlite3.Xsqlite3_bind_parameter_count(.tls, )
	return int(), nil
}

// int sqlite3_finalize(sqlite3_stmt *pStmt);
func ( *conn) ( uintptr) error {
	if  := sqlite3.Xsqlite3_finalize(.tls, );  != sqlite3.SQLITE_OK {
		return .errstr()
	}

	return nil
}

// int sqlite3_prepare_v2(
//   sqlite3 *db,            /* Database handle */
//   const char *zSql,       /* SQL statement, UTF-8 encoded */
//   int nByte,              /* Maximum length of zSql in bytes. */
//   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
//   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
// );
func ( *conn) ( *uintptr) ( uintptr,  error) {
	var ,  uintptr

	defer func() {
		.free()
		.free()
	}()

	if ,  = .malloc(int(ptrSize));  != nil {
		return 0, 
	}

	if ,  = .malloc(int(ptrSize));  != nil {
		return 0, 
	}

	for {
		switch  := sqlite3.Xsqlite3_prepare_v2(.tls, .db, *, -1, , );  {
		case sqlite3.SQLITE_OK:
			* = *(*uintptr)(unsafe.Pointer())
			return *(*uintptr)(unsafe.Pointer()), nil
		case sqliteLockedSharedcache, sqlite3.SQLITE_BUSY:
			if  := .retry(0);  != nil {
				return 0, 
			}
		default:
			return 0, .errstr()
		}
	}
}

// void sqlite3_interrupt(sqlite3*);
func ( *conn) ( uintptr) ( error) {
	sqlite3.Xsqlite3_interrupt(.tls, )
	return nil
}

// int sqlite3_extended_result_codes(sqlite3*, int onoff);
func ( *conn) ( bool) error {
	if  := sqlite3.Xsqlite3_extended_result_codes(.tls, .db, libc.Bool32());  != sqlite3.SQLITE_OK {
		return .errstr()
	}

	return nil
}

// int sqlite3_open_v2(
//   const char *filename,   /* Database filename (UTF-8) */
//   sqlite3 **ppDb,         /* OUT: SQLite db handle */
//   int flags,              /* Flags */
//   const char *zVfs        /* Name of VFS module to use */
// );
func ( *conn) ( string,  int32) (uintptr, error) {
	var ,  uintptr

	defer func() {
		if  != 0 {
			.free()
		}
		if  != 0 {
			.free()
		}
	}()

	,  := .malloc(int(ptrSize))
	if  != nil {
		return 0, 
	}

	if ,  = libc.CString();  != nil {
		return 0, 
	}

	if  := sqlite3.Xsqlite3_open_v2(.tls, , , , 0);  != sqlite3.SQLITE_OK {
		return 0, .errstr()
	}

	return *(*uintptr)(unsafe.Pointer()), nil
}

func ( *conn) ( int) (uintptr, error) {
	if  := libc.Xmalloc(.tls, types.Size_t());  != 0 ||  == 0 {
		return , nil
	}

	return 0, fmt.Errorf("sqlite: cannot allocate %d bytes of memory", )
}

func ( *conn) ( uintptr) {
	if  != 0 {
		libc.Xfree(.tls, )
	}
}

// const char *sqlite3_errstr(int);
func ( *conn) ( int32) error {
	 := sqlite3.Xsqlite3_errstr(.tls, )
	 := libc.GoString()
	 = sqlite3.Xsqlite3_errmsg(.tls, .db)
	switch  := libc.GoString(); {
	case  == :
		return &Error{msg: fmt.Sprintf("%s (%v)", , ), code: int()}
	default:
		return &Error{msg: fmt.Sprintf("%s: %s (%v)", , , ), code: int()}
	}
}

// Begin starts a transaction.
//
// Deprecated: Drivers should implement ConnBeginTx instead (or additionally).
func ( *conn) () (driver.Tx, error) {
	return .begin(context.Background(), driver.TxOptions{})
}

func ( *conn) ( context.Context,  driver.TxOptions) ( driver.Tx,  error) {
	return newTx()
}

// Close invalidates and potentially stops any current prepared statements and
// transactions, marking this connection as no longer in use.
//
// Because the sql package maintains a free pool of connections and only calls
// Close when there's a surplus of idle connections, it shouldn't be necessary
// for drivers to do their own connection caching.
func ( *conn) () error {
	if .db != 0 {
		if  := .closeV2(.db);  != nil {
			return 
		}

		.db = 0
	}
	if .tls != nil {
		.tls.Close()
		.tls = nil
	}
	return nil
}

// int sqlite3_close_v2(sqlite3*);
func ( *conn) ( uintptr) error {
	if  := sqlite3.Xsqlite3_close_v2(.tls, );  != sqlite3.SQLITE_OK {
		return .errstr()
	}

	return nil
}

// Execer is an optional interface that may be implemented by a Conn.
//
// If a Conn does not implement Execer, the sql package's DB.Exec will first
// prepare a query, execute the statement, and then close the statement.
//
// Exec may return ErrSkip.
//
// Deprecated: Drivers should implement ExecerContext instead.
func ( *conn) ( string,  []driver.Value) (driver.Result, error) {
	return .exec(context.Background(), , toNamedValues())
}

func ( *conn) ( context.Context,  string,  []driver.NamedValue) ( driver.Result,  error) {
	,  := .prepare(, )
	if  != nil {
		return nil, 
	}

	defer func() {
		if  := .Close();  != nil &&  == nil {
			 = 
		}
	}()

	return .(*stmt).exec(, )
}

// Prepare returns a prepared statement, bound to this connection.
func ( *conn) ( string) (driver.Stmt, error) {
	return .prepare(context.Background(), )
}

func ( *conn) ( context.Context,  string) ( driver.Stmt,  error) {
	//TODO use ctx
	return newStmt(, )
}

// Queryer is an optional interface that may be implemented by a Conn.
//
// If a Conn does not implement Queryer, the sql package's DB.Query will first
// prepare a query, execute the statement, and then close the statement.
//
// Query may return ErrSkip.
//
// Deprecated: Drivers should implement QueryerContext instead.
func ( *conn) ( string,  []driver.Value) (driver.Rows, error) {
	return .query(context.Background(), , toNamedValues())
}

func ( *conn) ( context.Context,  string,  []driver.NamedValue) ( driver.Rows,  error) {
	,  := .prepare(, )
	if  != nil {
		return nil, 
	}

	defer func() {
		if  := .Close();  != nil &&  == nil {
			 = 
		}
	}()

	return .(*stmt).query(, )
}

// Driver implements database/sql/driver.Driver.
type Driver struct{}

func () *Driver { return &Driver{} }

// Open returns a new connection to the database.  The name is a string in a
// driver-specific format.
//
// Open may return a cached connection (one previously closed), but doing so is
// unnecessary; the sql package maintains a pool of idle connections for
// efficient re-use.
//
// The returned connection is only used by one goroutine at a time.
func ( *Driver) ( string) (driver.Conn, error) {
	return newConn()
}