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

package sqlite

/*
#include <sqlite3.h>
#include <stdlib.h>
#include <string.h>

// These wrappers are necessary because SQLITE_TRANSIENT
// is a pointer constant, and cgo doesn't translate them correctly.
// The definition in sqlite3.h is:
//
// typedef void (*sqlite3_destructor_type)(void*);
// #define SQLITE_STATIC      ((sqlite3_destructor_type)0)
// #define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)

static int my_bind_text(sqlite3_stmt *stmt, int n, const char *p, int np) {
	return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT);
}
static int my_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
	return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT);
}

// just to get ride of "warning: passing argument 5 of ‘sqlite3_prepare_v2’ from incompatible pointer type [...] ‘const char **’ but argument is of type ‘char **’"
static int my_prepare_v2(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **ppStmt, char **pzTail) {
	return sqlite3_prepare_v2(db, zSql, nByte, ppStmt, (const char**)pzTail);
}
*/
import "C"

import (
	"errors"
	"fmt"
	"reflect"
	"time"
	"unsafe"
)

type StmtError struct {
	ConnError
	s *Stmt
}

func (e *StmtError) SQL() string {
	return e.s.SQL()
}

func (s *Stmt) error(rv C.int, details ...string) error {
	if s == nil {
		return errors.New("nil sqlite statement")
	}
	if rv == C.SQLITE_OK {
		return nil
	}
	err := ConnError{c: s.c, code: Errno(rv), msg: C.GoString(C.sqlite3_errmsg(s.c.db))}
	if len(details) > 0 {
		err.details = details[0]
	}
	return &StmtError{err, s}
}

func (s *Stmt) specificError(msg string, a ...interface{}) error {
	return &StmtError{ConnError{c: s.c, code: ErrSpecific, msg: fmt.Sprintf(msg, a...)}, s}
}

// SQL statement
type Stmt struct {
	c                  *Conn
	stmt               *C.sqlite3_stmt
	sql                string
	tail               string
	columnCount        int
	cols               map[string]int // cached columns index by name
	bindParameterCount int
	params             map[string]int // cached parameter index by name
	// Enable type check in Scan methods
	CheckTypeMismatch bool
}

// Compile an SQL statement and optionally bind values.
// If an error occurs while binding values, the statement is returned (not finalized).
// Example:
//	stmt, err := db.Prepare("SELECT 1 where 1 = ?", 1)
//	if err != nil {
//		...
//	}
//	defer stmt.Finalize()
//
// (See sqlite3_prepare_v2: http://sqlite.org/c3ref/prepare.html)
func (c *Conn) Prepare(cmd string, args ...interface{}) (*Stmt, error) {
	if c == nil {
		return nil, errors.New("nil sqlite database")
	}
	cmdstr := C.CString(cmd)
	defer C.free(unsafe.Pointer(cmdstr))
	var stmt *C.sqlite3_stmt
	var tail *C.char
	rv := C.my_prepare_v2(c.db, cmdstr, -1, &stmt, &tail)
	if rv != C.SQLITE_OK {
		return nil, c.error(rv, cmd)
	}
	var t string
	if tail != nil && C.strlen(tail) > 0 {
		t = C.GoString(tail)
	}
	s := &Stmt{c: c, stmt: stmt, tail: t, columnCount: -1, bindParameterCount: -1, CheckTypeMismatch: true}
	if len(args) > 0 {
		err := s.Bind(args...)
		if err != nil {
			return s, err
		}
	}
	return s, nil
}

// One-step statement execution.
// Don't use it with SELECT or anything that returns data.
// The Stmt is reset at each call.
// (See http://sqlite.org/c3ref/bind_blob.html, http://sqlite.org/c3ref/step.html)
func (s *Stmt) Exec(args ...interface{}) error {
	err := s.Bind(args...)
	if err != nil {
		return err
	}
	return s.exec()
}
func (s *Stmt) exec() error {
	rv := C.sqlite3_step(s.stmt)
	C.sqlite3_reset(s.stmt)
	if Errno(rv) != Done {
		return s.error(rv)
	}<commit_msg>Fix Prepare method: the Stmt is finalized when an error occurs while binding.<commit_after>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sqlite

/*
#include <sqlite3.h>
#include <stdlib.h>
#include <string.h>

// These wrappers are necessary because SQLITE_TRANSIENT
// is a pointer constant, and cgo doesn't translate them correctly.
// The definition in sqlite3.h is:
//
// typedef void (*sqlite3_destructor_type)(void*);
// #define SQLITE_STATIC      ((sqlite3_destructor_type)0)
// #define SQLITE_TRANSIENT   ((sqlite3_destructor_type)-1)

static int my_bind_text(sqlite3_stmt *stmt, int n, const char *p, int np) {
	return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT);
}
static int my_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
	return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT);
}

// just to get ride of "warning: passing argument 5 of ‘sqlite3_prepare_v2’ from incompatible pointer type [...] ‘const char **’ but argument is of type ‘char **’"
static int my_prepare_v2(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **ppStmt, char **pzTail) {
	return sqlite3_prepare_v2(db, zSql, nByte, ppStmt, (const char**)pzTail);
}
*/
import "C"

import (
	"errors"
	"fmt"
	"reflect"
	"time"
	"unsafe"
)

type StmtError struct {
	ConnError
	s *Stmt
}

func (e *StmtError) SQL() string {
	return e.s.SQL()
}

func (s *Stmt) error(rv C.int, details ...string) error {
	if s == nil {
		return errors.New("nil sqlite statement")
	}
	if rv == C.SQLITE_OK {
		return nil
	}
	err := ConnError{c: s.c, code: Errno(rv), msg: C.GoString(C.sqlite3_errmsg(s.c.db))}
	if len(details) > 0 {
		err.details = details[0]
	}
	return &StmtError{err, s}
}

func (s *Stmt) specificError(msg string, a ...interface{}) error {
	return &StmtError{ConnError{c: s.c, code: ErrSpecific, msg: fmt.Sprintf(msg, a...)}, s}
}

// SQL statement
type Stmt struct {
	c                  *Conn
	stmt               *C.sqlite3_stmt
	sql                string
	tail               string
	columnCount        int
	cols               map[string]int // cached columns index by name
	bindParameterCount int
	params             map[string]int // cached parameter index by name
	// Enable type check in Scan methods
	CheckTypeMismatch bool
}

// Compile an SQL statement and optionally bind values.
// Example:
//	stmt, err := db.Prepare("SELECT 1 where 1 = ?", 1)
//	if err != nil {
//		...
//	}
//	defer stmt.Finalize()
//
// (See sqlite3_prepare_v2: http://sqlite.org/c3ref/prepare.html)
func (c *Conn) Prepare(cmd string, args ...interface{}) (*Stmt, error) {
	if c == nil {
		return nil, errors.New("nil sqlite database")
	}
	cmdstr := C.CString(cmd)
	defer C.free(unsafe.Pointer(cmdstr))
	var stmt *C.sqlite3_stmt
	var tail *C.char
	rv := C.my_prepare_v2(c.db, cmdstr, -1, &stmt, &tail)
	if rv != C.SQLITE_OK {
		return nil, c.error(rv, cmd)
	}
	var t string
	if tail != nil && C.strlen(tail) > 0 {
		t = C.GoString(tail)
	}
	s := &Stmt{c: c, stmt: stmt, tail: t, columnCount: -1, bindParameterCount: -1, CheckTypeMismatch: true}
	if len(args) > 0 {
		err := s.Bind(args...)
		if err != nil {
			s.Finalize()
			return nil, err
		}
	}
	return s, nil
}

// One-step statement execution.
// Don't use it with SELECT or anything that returns data.
// The Stmt is reset at each call.
// (See http://sqlite.org/c3ref/bind_blob.html, http://sqlite.org/c3ref/step.html)
func (s *Stmt) Exec(args ...interface{}) error {
	err := s.Bind(args...)
	if err != nil {
		return err
	}
	return s.exec()
}
func (s *Stmt) exec() error {
	rv := C.sqlite3_step(s.stmt)
	C.sqlite3_reset(s.stmt)
	if Errno(rv) != Done {
		return s.error(rv)
	}
{'fraction_non_alphanumeric': 0.14274247491638797, 'fraction_numerical': 0.01177257525083612, 'mean_word_length': 3.267123287671233, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6040389', 'n_tokens_mistral': 2833, 'n_tokens_neox': 2751, 'n_words': 838}