sqlite.go 32.8 KB
Newer Older
cznic's avatar
cznic committed
1 2 3 4
// 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.

cznic's avatar
cznic committed
5
//go:generate go run generator.go
cznic's avatar
cznic committed
6
//go:generate go fmt ./...
cznic's avatar
cznic committed
7

cznic's avatar
cznic committed
8
package sqlite // import "modernc.org/sqlite"
cznic's avatar
cznic committed
9 10

import (
cznic's avatar
cznic committed
11
	"context"
cznic's avatar
cznic committed
12 13 14 15
	"database/sql"
	"database/sql/driver"
	"fmt"
	"io"
cznic's avatar
cznic committed
16 17 18
	"math"
	"reflect"
	"strings"
cznic's avatar
cznic committed
19 20 21
	"time"
	"unsafe"

cznic's avatar
cznic committed
22 23
	"modernc.org/libc"
	"modernc.org/libc/sys/types"
cznic's avatar
cznic committed
24
	"modernc.org/sqlite/lib"
cznic's avatar
cznic committed
25 26 27
)

var (
cznic's avatar
cznic committed
28 29 30 31 32
	_ driver.Conn   = (*conn)(nil)
	_ driver.Driver = (*Driver)(nil)
	//lint:ignore SA1019 TODO implement ExecerContext
	_ driver.Execer = (*conn)(nil)
	//lint:ignore SA1019 TODO implement QueryerContext
cznic's avatar
cznic committed
33 34 35 36 37 38 39 40 41 42 43 44
	_ driver.Queryer                        = (*conn)(nil)
	_ driver.Result                         = (*result)(nil)
	_ driver.Rows                           = (*rows)(nil)
	_ driver.Rows                           = noRows{}
	_ 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)
cznic's avatar
cznic committed
45 46 47
)

const (
cznic's avatar
cznic committed
48
	driverName              = "sqlite"
cznic's avatar
cznic committed
49 50
	ptrSize                 = unsafe.Sizeof(uintptr(0))
	sqliteLockedSharedcache = sqlite3.SQLITE_LOCKED | (1 << 8)
cznic's avatar
cznic committed
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
)

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

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

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

var (
	// ErrorCodeString maps Error.Code() to its string representation.
	ErrorCodeString = map[int]string{
cznic's avatar
cznic committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
		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)",
cznic's avatar
cznic committed
116
	}
cznic's avatar
cznic committed
117 118 119
)

func init() {
cznic's avatar
cznic committed
120 121
	//TODO configure page size to 4096
	tls := libc.NewTLS()
cznic's avatar
cznic committed
122
	if sqlite3.Xsqlite3_threadsafe(tls) == 0 {
123 124 125
		panic(fmt.Errorf("sqlite: thread safety configuration error"))
	}

cznic's avatar
cznic committed
126
	varArgs := libc.Xmalloc(tls, types.Size_t(ptrSize))
cznic's avatar
cznic committed
127 128 129 130 131
	if varArgs == 0 {
		panic(fmt.Errorf("cannot allocate memory"))
	}

	// int sqlite3_config(int, ...);
cznic's avatar
cznic committed
132
	if rc := sqlite3.Xsqlite3_config(tls, sqlite3.SQLITE_CONFIG_MUTEX, libc.VaList(varArgs, uintptr(unsafe.Pointer(&mutexMethods)))); rc != sqlite3.SQLITE_OK {
cznic's avatar
cznic committed
133
		p := sqlite3.Xsqlite3_errstr(tls, rc)
cznic's avatar
cznic committed
134
		str := libc.GoString(p)
cznic's avatar
cznic committed
135 136 137
		panic(fmt.Errorf("sqlite: failed to configure mutex methods: %v", str))
	}

cznic's avatar
cznic committed
138
	libc.Xfree(tls, varArgs)
cznic's avatar
cznic committed
139
	tls.Close()
cznic's avatar
cznic committed
140
	sql.Register(driverName, newDriver())
cznic's avatar
cznic committed
141 142 143
}

type result struct {
144
	lastInsertID int64
cznic's avatar
cznic committed
145 146 147
	rowsAffected int
}

cznic's avatar
cznic committed
148 149 150
func newResult(c *conn) (_ *result, err error) {
	r := &result{}
	if r.rowsAffected, err = c.changes(); err != nil {
cznic's avatar
cznic committed
151 152 153
		return nil, err
	}

cznic's avatar
cznic committed
154
	if r.lastInsertID, err = c.lastInsertRowID(); err != nil {
cznic's avatar
cznic committed
155 156 157 158 159 160 161 162 163 164 165 166 167
		return nil, err
	}

	return r, nil
}

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

168
	return r.lastInsertID, nil
cznic's avatar
cznic committed
169 170 171 172 173 174 175 176 177 178 179 180
}

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

	return int64(r.rowsAffected), nil
}

type rows struct {
cznic's avatar
cznic committed
181
	allocs  []uintptr
cznic's avatar
cznic committed
182
	c       *conn
cznic's avatar
cznic committed
183
	columns []string
cznic's avatar
cznic committed
184
	pstmt   uintptr
cznic's avatar
cznic committed
185 186

	doStep bool
cznic's avatar
cznic committed
187
	empty  bool
cznic's avatar
cznic committed
188 189
}

cznic's avatar
cznic committed
190
func newRows(c *conn, pstmt uintptr, allocs []uintptr, empty bool) (r *rows, err error) {
cznic's avatar
cznic committed
191 192 193 194 195 196
	defer func() {
		if err != nil {
			c.finalize(pstmt)
			r = nil
		}
	}()
cznic's avatar
cznic committed
197

cznic's avatar
cznic committed
198 199
	r = &rows{c: c, pstmt: pstmt, allocs: allocs}
	n, err := c.columnCount(pstmt)
cznic's avatar
cznic committed
200 201 202 203 204 205
	if err != nil {
		return nil, err
	}

	r.columns = make([]string, n)
	for i := range r.columns {
cznic's avatar
cznic committed
206
		if r.columns[i], err = r.c.columnName(pstmt, i); err != nil {
cznic's avatar
cznic committed
207 208 209 210 211 212 213
			return nil, err
		}
	}

	return r, nil
}

cznic's avatar
cznic committed
214 215 216 217 218 219 220 221 222
// Close closes the rows iterator.
func (r *rows) Close() (err error) {
	for _, v := range r.allocs {
		r.c.free(v)
	}
	r.allocs = nil
	return r.c.finalize(r.pstmt)
}

cznic's avatar
cznic committed
223 224 225 226 227 228 229 230 231 232 233 234
// 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 (r *rows) Columns() (c []string) {
	return r.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 (r *rows) Next(dest []driver.Value) (err error) {
cznic's avatar
cznic committed
235 236 237 238
	if r.empty {
		return io.EOF
	}

cznic's avatar
cznic committed
239
	rc := sqlite3.SQLITE_ROW
240
	if r.doStep {
cznic's avatar
cznic committed
241
		if rc, err = r.c.step(r.pstmt); err != nil {
cznic's avatar
cznic committed
242 243 244 245
			return err
		}
	}

246
	r.doStep = true
cznic's avatar
cznic committed
247
	switch rc {
cznic's avatar
cznic committed
248
	case sqlite3.SQLITE_ROW:
cznic's avatar
cznic committed
249
		if g, e := len(dest), len(r.columns); g != e {
cznic's avatar
cznic committed
250
			return fmt.Errorf("sqlite: Next: have %v destination values, expected %v", g, e)
cznic's avatar
cznic committed
251 252 253
		}

		for i := range dest {
cznic's avatar
cznic committed
254
			ct, err := r.c.columnType(r.pstmt, i)
cznic's avatar
cznic committed
255 256 257 258 259
			if err != nil {
				return err
			}

			switch ct {
cznic's avatar
cznic committed
260
			case sqlite3.SQLITE_INTEGER:
cznic's avatar
cznic committed
261
				v, err := r.c.columnInt64(r.pstmt, i)
cznic's avatar
cznic committed
262 263 264 265 266
				if err != nil {
					return err
				}

				dest[i] = v
cznic's avatar
cznic committed
267
			case sqlite3.SQLITE_FLOAT:
cznic's avatar
cznic committed
268
				v, err := r.c.columnDouble(r.pstmt, i)
cznic's avatar
cznic committed
269 270 271 272 273
				if err != nil {
					return err
				}

				dest[i] = v
cznic's avatar
cznic committed
274
			case sqlite3.SQLITE_TEXT:
cznic's avatar
cznic committed
275
				v, err := r.c.columnText(r.pstmt, i)
cznic's avatar
cznic committed
276 277 278 279 280
				if err != nil {
					return err
				}

				dest[i] = v
cznic's avatar
cznic committed
281
			case sqlite3.SQLITE_BLOB:
cznic's avatar
cznic committed
282
				v, err := r.c.columnBlob(r.pstmt, i)
cznic's avatar
cznic committed
283 284 285 286 287
				if err != nil {
					return err
				}

				dest[i] = v
cznic's avatar
cznic committed
288
			case sqlite3.SQLITE_NULL:
cznic's avatar
cznic committed
289 290
				dest[i] = nil
			default:
cznic's avatar
cznic committed
291
				return fmt.Errorf("internal error: rc %d", rc)
cznic's avatar
cznic committed
292 293 294
			}
		}
		return nil
cznic's avatar
cznic committed
295
	case sqlite3.SQLITE_DONE:
cznic's avatar
cznic committed
296 297
		return io.EOF
	default:
cznic's avatar
cznic committed
298
		return r.c.errstr(int32(rc))
cznic's avatar
cznic committed
299 300 301
	}
}

cznic's avatar
cznic committed
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
// 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 (r *rows) ColumnTypeDatabaseTypeName(index int) string {
	return strings.ToUpper(r.c.columnDeclType(r.pstmt, index))
}

// 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 (r *rows) ColumnTypeLength(index int) (length int64, ok bool) {
	t, err := r.c.columnType(r.pstmt, index)
	if err != nil {
		return 0, false
	}

	switch t {
	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 (r *rows) ColumnTypeNullable(index int) (nullable, ok 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 (r *rows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok 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 (r *rows) ColumnTypeScanType(index int) reflect.Type {
	t, err := r.c.columnType(r.pstmt, index)
	if err != nil {
		return reflect.TypeOf("")
	}

	switch t {
	case sqlite3.SQLITE_INTEGER:
		switch strings.ToLower(r.c.columnDeclType(r.pstmt, index)) {
		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("")
	}
}

cznic's avatar
cznic committed
396
type stmt struct {
cznic's avatar
cznic committed
397
	c    *conn
cznic's avatar
cznic committed
398
	psql uintptr
cznic's avatar
cznic committed
399 400
}

401
func newStmt(c *conn, sql string) (*stmt, error) {
cznic's avatar
cznic committed
402
	p, err := libc.CString(sql)
cznic's avatar
cznic committed
403 404 405 406
	if err != nil {
		return nil, err
	}

cznic's avatar
cznic committed
407
	return &stmt{c: c, psql: p}, nil
cznic's avatar
cznic committed
408 409 410 411 412 413
}

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

cznic's avatar
cznic committed
419
// Exec executes a query that doesn't return rows, such as an INSERT or UPDATE.
cznic's avatar
cznic committed
420 421
//
//
cznic's avatar
cznic committed
422 423 424 425
// Deprecated: Drivers should implement StmtExecContext instead (or
// additionally).
func (s *stmt) Exec(args []driver.Value) (driver.Result, error) { //TODO StmtExecContext
	return s.exec(context.Background(), toNamedValues(args))
cznic's avatar
cznic committed
426 427
}

cznic's avatar
cznic committed
428 429 430 431 432 433 434
// toNamedValues converts []driver.Value to []driver.NamedValue
func toNamedValues(vals []driver.Value) (r []driver.NamedValue) {
	r = make([]driver.NamedValue, len(vals))
	for i, val := range vals {
		r[i] = driver.NamedValue{Value: val, Ordinal: i + 1}
	}
	return r
435 436
}

cznic's avatar
cznic committed
437
func (s *stmt) exec(ctx context.Context, args []driver.NamedValue) (r driver.Result, err error) {
cznic's avatar
cznic committed
438
	var pstmt uintptr
439 440

	donech := make(chan struct{})
cznic's avatar
cznic committed
441

442 443 444
	go func() {
		select {
		case <-ctx.Done():
cznic's avatar
cznic committed
445
			if pstmt != 0 {
cznic's avatar
cznic committed
446
				s.c.interrupt(s.c.db)
447 448 449 450 451
			}
		case <-donech:
		}
	}()

cznic's avatar
cznic committed
452 453 454 455 456
	defer func() {
		pstmt = 0
		close(donech)
	}()

cznic's avatar
cznic committed
457
	for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0; {
cznic's avatar
cznic committed
458
		if pstmt, err = s.c.prepareV2(&psql); err != nil {
cznic's avatar
cznic committed
459 460 461
			return nil, err
		}

cznic's avatar
cznic committed
462
		if pstmt == 0 {
cznic's avatar
cznic committed
463 464 465
			continue
		}

cznic's avatar
cznic committed
466 467 468 469 470 471
		if err := func() (err error) {
			defer func() {
				if e := s.c.finalize(pstmt); e != nil && err == nil {
					err = e
				}
			}()
cznic's avatar
cznic committed
472

cznic's avatar
cznic committed
473 474 475
			n, err := s.c.bindParameterCount(pstmt)
			if err != nil {
				return err
cznic's avatar
cznic committed
476
			}
477

cznic's avatar
cznic committed
478 479 480 481 482
			if n != 0 {
				allocs, err := s.c.bind(pstmt, n, args)
				if err != nil {
					return err
				}
cznic's avatar
cznic committed
483

cznic's avatar
cznic committed
484 485 486 487 488 489 490
				if len(allocs) != 0 {
					defer func() {
						for _, v := range allocs {
							s.c.free(v)
						}
					}()
				}
cznic's avatar
cznic committed
491
			}
cznic's avatar
cznic committed
492 493 494 495 496 497 498

			rc, err := s.c.step(pstmt)
			if err != nil {
				return err
			}

			switch rc & 0xff {
cznic's avatar
cznic committed
499
			case sqlite3.SQLITE_DONE, sqlite3.SQLITE_ROW:
cznic's avatar
cznic committed
500 501 502 503 504 505 506
				// nop
			default:
				return s.c.errstr(int32(rc))
			}

			return nil
		}(); err != nil {
cznic's avatar
cznic committed
507 508 509
			return nil, err
		}
	}
cznic's avatar
cznic committed
510 511 512 513 514 515 516 517 518 519 520 521 522 523
	return newResult(s.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 (s *stmt) NumInput() (n int) {
	return -1
cznic's avatar
cznic committed
524 525
}

cznic's avatar
cznic committed
526 527 528 529 530 531
// Query executes a query that may return rows, such as a
// SELECT.
//
// Deprecated: Drivers should implement StmtQueryContext instead (or
// additionally).
func (s *stmt) Query(args []driver.Value) (driver.Rows, error) { //TODO StmtQueryContext
532 533 534
	return s.query(context.Background(), toNamedValues(args))
}

cznic's avatar
cznic committed
535
func (s *stmt) query(ctx context.Context, args []driver.NamedValue) (r driver.Rows, err error) {
cznic's avatar
cznic committed
536
	var pstmt uintptr
537 538

	donech := make(chan struct{})
cznic's avatar
cznic committed
539

540 541 542
	go func() {
		select {
		case <-ctx.Done():
cznic's avatar
cznic committed
543
			if pstmt != 0 {
cznic's avatar
cznic committed
544
				s.c.interrupt(s.c.db)
545 546 547 548 549
			}
		case <-donech:
		}
	}()

cznic's avatar
cznic committed
550 551 552 553 554
	defer func() {
		pstmt = 0
		close(donech)
	}()

cznic's avatar
cznic committed
555 556
	var allocs []uintptr
	for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0; {
cznic's avatar
cznic committed
557
		if pstmt, err = s.c.prepareV2(&psql); err != nil {
cznic's avatar
cznic committed
558 559 560
			return nil, err
		}

cznic's avatar
cznic committed
561
		if pstmt == 0 {
cznic's avatar
cznic committed
562 563 564
			continue
		}

cznic's avatar
cznic committed
565 566 567 568 569 570
		if err = func() (err error) {
			defer func() {
				if e := s.c.finalize(pstmt); e != nil && err == nil {
					err = e
				}
			}()
cznic's avatar
cznic committed
571

cznic's avatar
cznic committed
572 573 574
			n, err := s.c.bindParameterCount(pstmt)
			if err != nil {
				return err
cznic's avatar
cznic committed
575
			}
576

cznic's avatar
cznic committed
577 578 579 580 581
			if n != 0 {
				a, err := s.c.bind(pstmt, n, args)
				if err != nil {
					return err
				}
cznic's avatar
cznic committed
582

cznic's avatar
cznic committed
583 584
				if len(a) != 0 {
					allocs = append(allocs, a...)
cznic's avatar
cznic committed
585
				}
cznic's avatar
cznic committed
586
			}
cznic's avatar
cznic committed
587

cznic's avatar
cznic committed
588 589 590
			rc, err := s.c.step(pstmt)
			if err != nil {
				return err
cznic's avatar
cznic committed
591 592
			}

cznic's avatar
cznic committed
593
			switch rc & 0xff {
cznic's avatar
cznic committed
594
			case sqlite3.SQLITE_ROW:
cznic's avatar
cznic committed
595
				if r, err = newRows(s.c, pstmt, allocs, false); err != nil {
cznic's avatar
cznic committed
596 597 598 599 600
					return err
				}

				pstmt = 0
				return nil
cznic's avatar
cznic committed
601
			case sqlite3.SQLITE_DONE:
602 603 604 605 606
				if r == nil {
					pstmt = 0
					r = noRows{}
					return nil
				}
cznic's avatar
cznic committed
607 608 609
				// nop
			default:
				return s.c.errstr(int32(rc))
cznic's avatar
cznic committed
610
			}
cznic's avatar
cznic committed
611

cznic's avatar
cznic committed
612
			if *(*byte)(unsafe.Pointer(psql)) == 0 {
cznic's avatar
cznic committed
613 614 615 616 617 618
				if r, err = newRows(s.c, pstmt, allocs, true); err != nil {
					return err
				}

				pstmt = 0
			}
cznic's avatar
cznic committed
619 620
			return nil
		}(); err != nil {
cznic's avatar
cznic committed
621 622 623
			return nil, err
		}
	}
cznic's avatar
cznic committed
624
	return r, err
cznic's avatar
cznic committed
625 626
}

627 628 629 630 631 632
type noRows struct{}

func (noRows) Columns() []string         { return nil }
func (noRows) Close() error              { return nil }
func (noRows) Next([]driver.Value) error { return sql.ErrNoRows }

cznic's avatar
cznic committed
633 634 635 636 637 638 639 640
type tx struct {
	c *conn
}

func newTx(c *conn) (*tx, error) {
	r := &tx{c: c}
	if err := r.exec(context.Background(), "begin"); err != nil {
		return nil, err
cznic's avatar
cznic committed
641 642
	}

cznic's avatar
cznic committed
643
	return r, nil
cznic's avatar
cznic committed
644 645
}

cznic's avatar
cznic committed
646 647 648 649
// Commit implements driver.Tx.
func (t *tx) Commit() (err error) {
	return t.exec(context.Background(), "commit")
}
cznic's avatar
cznic committed
650

cznic's avatar
cznic committed
651 652 653
// Rollback implements driver.Tx.
func (t *tx) Rollback() (err error) {
	return t.exec(context.Background(), "rollback")
cznic's avatar
cznic committed
654 655
}

cznic's avatar
cznic committed
656
func (t *tx) exec(ctx context.Context, sql string) (err error) {
cznic's avatar
cznic committed
657
	psql, err := libc.CString(sql)
cznic's avatar
cznic committed
658 659 660 661
	if err != nil {
		return err
	}

cznic's avatar
cznic committed
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
	defer t.c.free(psql)

	//TODO use t.conn.ExecContext() instead
	donech := make(chan struct{})

	defer close(donech)

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

cznic's avatar
cznic committed
677
	if rc := sqlite3.Xsqlite3_exec(t.c.tls, t.c.db, psql, 0, 0, 0); rc != sqlite3.SQLITE_OK {
cznic's avatar
cznic committed
678
		return t.c.errstr(rc)
cznic's avatar
cznic committed
679 680 681 682 683
	}

	return nil
}

cznic's avatar
cznic committed
684
type conn struct {
cznic's avatar
cznic committed
685
	db  uintptr // *sqlite3.Xsqlite3
cznic's avatar
cznic committed
686
	tls *libc.TLS
cznic's avatar
cznic committed
687 688 689
}

func newConn(name string) (*conn, error) {
cznic's avatar
cznic committed
690
	c := &conn{tls: libc.NewTLS()}
cznic's avatar
cznic committed
691 692
	db, err := c.openV2(
		name,
cznic's avatar
cznic committed
693 694 695
		sqlite3.SQLITE_OPEN_READWRITE|sqlite3.SQLITE_OPEN_CREATE|
			sqlite3.SQLITE_OPEN_FULLMUTEX|
			sqlite3.SQLITE_OPEN_URI,
cznic's avatar
cznic committed
696
	)
cznic's avatar
cznic committed
697
	if err != nil {
cznic's avatar
cznic committed
698
		return nil, err
cznic's avatar
cznic committed
699 700
	}

cznic's avatar
cznic committed
701 702 703
	c.db = db
	if err = c.extendedResultCodes(true); err != nil {
		return nil, err
cznic's avatar
cznic committed
704 705
	}

706 707 708
	// Default is set at compile time to 1024 because testfixture hard codes that value, fix it at runtime.
	_, err = c.Exec("PRAGMA page_size = 4096;", nil)
	return c, err
cznic's avatar
cznic committed
709 710
}

cznic's avatar
cznic committed
711
// const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
cznic's avatar
cznic committed
712 713
func (c *conn) columnBlob(pstmt uintptr, iCol int) (v []byte, err error) {
	p := sqlite3.Xsqlite3_column_blob(c.tls, pstmt, int32(iCol))
cznic's avatar
cznic committed
714 715 716 717
	len, err := c.columnBytes(pstmt, iCol)
	if err != nil {
		return nil, err
	}
718

cznic's avatar
cznic committed
719 720 721 722 723
	if p == 0 || len == 0 {
		return nil, nil
	}

	v = make([]byte, len)
cznic's avatar
cznic committed
724
	copy(v, (*libc.RawMem)(unsafe.Pointer(p))[:len:len])
cznic's avatar
cznic committed
725 726 727 728
	return v, nil
}

// int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
cznic's avatar
cznic committed
729 730
func (c *conn) columnBytes(pstmt uintptr, iCol int) (_ int, err error) {
	v := sqlite3.Xsqlite3_column_bytes(c.tls, pstmt, int32(iCol))
cznic's avatar
cznic committed
731 732 733 734
	return int(v), nil
}

// const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
cznic's avatar
cznic committed
735 736
func (c *conn) columnText(pstmt uintptr, iCol int) (v string, err error) {
	p := sqlite3.Xsqlite3_column_text(c.tls, pstmt, int32(iCol))
cznic's avatar
cznic committed
737 738 739 740 741 742 743 744 745 746
	len, err := c.columnBytes(pstmt, iCol)
	if err != nil {
		return "", err
	}

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

	b := make([]byte, len)
cznic's avatar
cznic committed
747
	copy(b, (*libc.RawMem)(unsafe.Pointer(p))[:len:len])
cznic's avatar
cznic committed
748 749 750 751
	return string(b), nil
}

// double sqlite3_column_double(sqlite3_stmt*, int iCol);
cznic's avatar
cznic committed
752 753
func (c *conn) columnDouble(pstmt uintptr, iCol int) (v float64, err error) {
	v = sqlite3.Xsqlite3_column_double(c.tls, pstmt, int32(iCol))
cznic's avatar
cznic committed
754 755 756 757
	return v, nil
}

// sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
cznic's avatar
cznic committed
758 759
func (c *conn) columnInt64(pstmt uintptr, iCol int) (v int64, err error) {
	v = sqlite3.Xsqlite3_column_int64(c.tls, pstmt, int32(iCol))
cznic's avatar
cznic committed
760 761 762 763
	return v, nil
}

// int sqlite3_column_type(sqlite3_stmt*, int iCol);
cznic's avatar
cznic committed
764 765
func (c *conn) columnType(pstmt uintptr, iCol int) (_ int, err error) {
	v := sqlite3.Xsqlite3_column_type(c.tls, pstmt, int32(iCol))
cznic's avatar
cznic committed
766 767 768
	return int(v), nil
}

cznic's avatar
cznic committed
769 770 771 772 773
// const char *sqlite3_column_decltype(sqlite3_stmt*,int);
func (c *conn) columnDeclType(pstmt uintptr, iCol int) string {
	return libc.GoString(sqlite3.Xsqlite3_column_decltype(c.tls, pstmt, int32(iCol)))
}

cznic's avatar
cznic committed
774
// const char *sqlite3_column_name(sqlite3_stmt*, int N);
cznic's avatar
cznic committed
775 776
func (c *conn) columnName(pstmt uintptr, n int) (string, error) {
	p := sqlite3.Xsqlite3_column_name(c.tls, pstmt, int32(n))
cznic's avatar
cznic committed
777
	return libc.GoString(p), nil
cznic's avatar
cznic committed
778 779 780
}

// int sqlite3_column_count(sqlite3_stmt *pStmt);
cznic's avatar
cznic committed
781 782
func (c *conn) columnCount(pstmt uintptr) (_ int, err error) {
	v := sqlite3.Xsqlite3_column_count(c.tls, pstmt)
cznic's avatar
cznic committed
783 784 785 786 787
	return int(v), nil
}

// sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
func (c *conn) lastInsertRowID() (v int64, _ error) {
cznic's avatar
cznic committed
788
	return sqlite3.Xsqlite3_last_insert_rowid(c.tls, c.db), nil
cznic's avatar
cznic committed
789 790 791 792
}

// int sqlite3_changes(sqlite3*);
func (c *conn) changes() (int, error) {
cznic's avatar
cznic committed
793
	v := sqlite3.Xsqlite3_changes(c.tls, c.db)
cznic's avatar
cznic committed
794 795 796 797
	return int(v), nil
}

// int sqlite3_step(sqlite3_stmt*);
cznic's avatar
cznic committed
798
func (c *conn) step(pstmt uintptr) (int, error) {
cznic's avatar
cznic committed
799
	for {
cznic's avatar
cznic committed
800 801
		switch rc := sqlite3.Xsqlite3_step(c.tls, pstmt); rc {
		case sqliteLockedSharedcache, sqlite3.SQLITE_BUSY:
cznic's avatar
cznic committed
802
			if err := c.retry(pstmt); err != nil {
cznic's avatar
cznic committed
803
				return sqlite3.SQLITE_LOCKED, err
cznic's avatar
cznic committed
804 805 806 807 808 809 810
			}
		default:
			return int(rc), nil
		}
	}
}

cznic's avatar
cznic committed
811 812
func (c *conn) retry(pstmt uintptr) error {
	mu := mutexAlloc(c.tls, sqlite3.SQLITE_MUTEX_FAST)
cznic's avatar
cznic committed
813
	(*mutex)(unsafe.Pointer(mu)).enter(c.tls.ID) // Block
cznic's avatar
cznic committed
814
	rc := sqlite3.Xsqlite3_unlock_notify(
cznic's avatar
cznic committed
815 816
		c.tls,
		c.db,
cznic's avatar
cznic committed
817
		*(*uintptr)(unsafe.Pointer(&struct {
cznic's avatar
cznic committed
818
			f func(*libc.TLS, uintptr, int32)
cznic's avatar
cznic committed
819 820 821
		}{unlockNotify})),
		mu,
	)
cznic's avatar
cznic committed
822
	if rc == sqlite3.SQLITE_LOCKED { // Deadlock, see https://www.sqlite.org/c3ref/unlock_notify.html
cznic's avatar
cznic committed
823
		(*mutex)(unsafe.Pointer(mu)).leave(c.tls.ID) // Clear
cznic's avatar
cznic committed
824 825 826 827
		mutexFree(c.tls, mu)
		return c.errstr(rc)
	}

cznic's avatar
cznic committed
828 829
	(*mutex)(unsafe.Pointer(mu)).enter(c.tls.ID) // Wait
	(*mutex)(unsafe.Pointer(mu)).leave(c.tls.ID) // Clear
cznic's avatar
cznic committed
830 831
	mutexFree(c.tls, mu)
	if pstmt != 0 {
cznic's avatar
cznic committed
832
		sqlite3.Xsqlite3_reset(c.tls, pstmt)
cznic's avatar
cznic committed
833 834 835 836
	}
	return nil
}

cznic's avatar
cznic committed
837
func unlockNotify(t *libc.TLS, ppArg uintptr, nArg int32) {
cznic's avatar
cznic committed
838
	for i := int32(0); i < nArg; i++ {
cznic's avatar
cznic committed
839 840 841
		mu := *(*uintptr)(unsafe.Pointer(ppArg))
		(*mutex)(unsafe.Pointer(mu)).leave(t.ID) // Signal
		ppArg += ptrSize
cznic's avatar
cznic committed
842 843 844
	}
}

cznic's avatar
cznic committed
845
func (c *conn) bind(pstmt uintptr, n int, args []driver.NamedValue) (allocs []uintptr, err error) {
cznic's avatar
cznic committed
846 847 848 849 850 851 852 853 854 855 856 857
	defer func() {
		if err == nil {
			return
		}

		for _, v := range allocs {
			c.free(v)
		}
		allocs = nil
	}()

	for i := 1; i <= n; i++ {
cznic's avatar
cznic committed
858
		var p uintptr
cznic's avatar
cznic committed
859 860 861 862 863 864 865 866 867 868 869
		name, err := c.bindParameterName(pstmt, i)
		if err != nil {
			return allocs, err
		}

		var v driver.NamedValue
		for _, v = range args {
			if name != "" {
				// sqlite supports '$', '@' and ':' prefixes for string
				// identifiers and '?' for numeric, so we cannot
				// combine different prefixes with the same name
870 871 872 873 874 875 876 877 878 879 880 881 882 883
				// because `database/sql` requires variable names
				// to start with a letter
				if name[1:] == v.Name[:] {
					break
				}
			} else {
				if v.Ordinal == i {
					break
				}
			}
		}

		if v.Ordinal == 0 {
			if name != "" {
cznic's avatar
cznic committed
884
				return allocs, fmt.Errorf("missing named argument %q", name[1:])
885
			}
886

cznic's avatar
cznic committed
887
			return allocs, fmt.Errorf("missing argument with %d index", i)
888
		}
cznic's avatar
cznic committed
889

890
		switch x := v.Value.(type) {
cznic's avatar
cznic committed
891
		case int64:
cznic's avatar
cznic committed
892 893
			if err := c.bindInt64(pstmt, i, x); err != nil {
				return allocs, err
cznic's avatar
cznic committed
894 895
			}
		case float64:
cznic's avatar
cznic committed
896 897
			if err := c.bindDouble(pstmt, i, x); err != nil {
				return allocs, err
cznic's avatar
cznic committed
898 899 900 901 902 903
			}
		case bool:
			v := 0
			if x {
				v = 1
			}
cznic's avatar
cznic committed
904 905
			if err := c.bindInt(pstmt, i, v); err != nil {
				return allocs, err
cznic's avatar
cznic committed
906 907
			}
		case []byte:
cznic's avatar
cznic committed
908 909
			if p, err = c.bindBlob(pstmt, i, x); err != nil {
				return allocs, err
cznic's avatar
cznic committed
910 911
			}
		case string:
cznic's avatar
cznic committed
912 913
			if p, err = c.bindText(pstmt, i, x); err != nil {
				return allocs, err
cznic's avatar
cznic committed
914 915
			}
		case time.Time:
cznic's avatar
cznic committed
916 917
			if p, err = c.bindText(pstmt, i, x.String()); err != nil {
				return allocs, err
cznic's avatar
cznic committed
918
			}
919 920 921 922
		case nil:
			if p, err = c.bindNull(pstmt, i); err != nil {
				return allocs, err
			}
cznic's avatar
cznic committed
923
		default:
cznic's avatar
cznic committed
924 925 926 927
			return allocs, fmt.Errorf("sqlite: invalid driver.Value type %T", x)
		}
		if p != 0 {
			allocs = append(allocs, p)
cznic's avatar
cznic committed
928 929
		}
	}
cznic's avatar
cznic committed
930 931 932
	return allocs, nil
}

933 934 935 936 937 938 939 940 941
// int sqlite3_bind_null(sqlite3_stmt*, int);
func (c *conn) bindNull(pstmt uintptr, idx1 int) (uintptr, error) {
	if rc := sqlite3.Xsqlite3_bind_null(c.tls, pstmt, int32(idx1)); rc != sqlite3.SQLITE_OK {
		return 0, c.errstr(rc)
	}

	return 0, nil
}

cznic's avatar
cznic committed
942
// int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
cznic's avatar
cznic committed
943
func (c *conn) bindText(pstmt uintptr, idx1 int, value string) (uintptr, error) {
cznic's avatar
cznic committed
944
	p, err := libc.CString(value)
cznic's avatar
cznic committed
945 946 947 948
	if err != nil {
		return 0, err
	}

cznic's avatar
cznic committed
949
	if rc := sqlite3.Xsqlite3_bind_text(c.tls, pstmt, int32(idx1), p, int32(len(value)), 0); rc != sqlite3.SQLITE_OK {
cznic's avatar
cznic committed
950 951 952 953 954 955 956 957
		c.free(p)
		return 0, c.errstr(rc)
	}

	return p, nil
}

// int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
cznic's avatar
cznic committed
958
func (c *conn) bindBlob(pstmt uintptr, idx1 int, value []byte) (uintptr, error) {
cznic's avatar
cznic committed
959 960 961 962 963
	p, err := c.malloc(len(value))
	if err != nil {
		return 0, err
	}

cznic's avatar
cznic committed
964
	copy((*libc.RawMem)(unsafe.Pointer(p))[:len(value):len(value)], value)
cznic's avatar
cznic committed
965
	if rc := sqlite3.Xsqlite3_bind_blob(c.tls, pstmt, int32(idx1), p, int32(len(value)), 0); rc != sqlite3.SQLITE_OK {
cznic's avatar
cznic committed
966 967 968 969 970 971 972 973
		c.free(p)
		return 0, c.errstr(rc)
	}

	return p, nil
}

// int sqlite3_bind_int(sqlite3_stmt*, int, int);
cznic's avatar
cznic committed
974 975
func (c *conn) bindInt(pstmt uintptr, idx1, value int) (err error) {
	if rc := sqlite3.Xsqlite3_bind_int(c.tls, pstmt, int32(idx1), int32(value)); rc != sqlite3.SQLITE_OK {
cznic's avatar
cznic committed
976 977 978
		return c.errstr(rc)
	}

cznic's avatar
cznic committed
979 980 981
	return nil
}

cznic's avatar
cznic committed
982
// int sqlite3_bind_double(sqlite3_stmt*, int, double);
cznic's avatar
cznic committed
983 984
func (c *conn) bindDouble(pstmt uintptr, idx1 int, value float64) (err error) {
	if rc := sqlite3.Xsqlite3_bind_double(c.tls, pstmt, int32(idx1), value); rc != 0 {
cznic's avatar
cznic committed
985 986 987 988 989 990 991
		return c.errstr(rc)
	}

	return nil
}

// int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
cznic's avatar
cznic committed
992 993
func (c *conn) bindInt64(pstmt uintptr, idx1 int, value int64) (err error) {
	if rc := sqlite3.Xsqlite3_bind_int64(c.tls, pstmt, int32(idx1), value); rc != sqlite3.SQLITE_OK {
cznic's avatar
cznic committed
994 995 996 997
		return c.errstr(rc)
	}

	return nil
cznic's avatar
cznic committed
998 999
}

1000
// const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
cznic's avatar
cznic committed
1001 1002
func (c *conn) bindParameterName(pstmt uintptr, i int) (string, error) {
	p := sqlite3.Xsqlite3_bind_parameter_name(c.tls, pstmt, int32(i))
cznic's avatar
cznic committed
1003
	return libc.GoString(p), nil
1004 1005
}

cznic's avatar
cznic committed
1006
// int sqlite3_bind_parameter_count(sqlite3_stmt*);
cznic's avatar
cznic committed
1007 1008
func (c *conn) bindParameterCount(pstmt uintptr) (_ int, err error) {
	r := sqlite3.Xsqlite3_bind_parameter_count(c.tls, pstmt)
cznic's avatar
cznic committed
1009 1010 1011
	return int(r), nil
}

cznic's avatar
cznic committed
1012
// int sqlite3_finalize(sqlite3_stmt *pStmt);
cznic's avatar
cznic committed
1013 1014
func (c *conn) finalize(pstmt uintptr) error {
	if rc := sqlite3.Xsqlite3_finalize(c.tls, pstmt); rc != sqlite3.SQLITE_OK {
cznic's avatar
cznic committed
1015
		return c.errstr(rc)
cznic's avatar
cznic committed
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
	}

	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 */
// );
cznic's avatar
cznic committed
1028 1029
func (c *conn) prepareV2(zSQL *uintptr) (pstmt uintptr, err error) {
	var ppstmt, pptail uintptr
cznic's avatar
cznic committed
1030

cznic's avatar
cznic committed
1031 1032 1033 1034
	defer func() {
		c.free(ppstmt)
		c.free(pptail)
	}()
cznic's avatar
cznic committed
1035

cznic's avatar
cznic committed
1036
	if ppstmt, err = c.malloc(int(ptrSize)); err != nil {
cznic's avatar
cznic committed
1037 1038
		return 0, err
	}
cznic's avatar
cznic committed
1039

cznic's avatar
cznic committed
1040
	if pptail, err = c.malloc(int(ptrSize)); err != nil {
cznic's avatar
cznic committed
1041
		return 0, err
cznic's avatar
cznic committed
1042 1043
	}

cznic's avatar
cznic committed
1044
	for {
cznic's avatar
cznic committed
1045 1046 1047 1048 1049
		switch rc := sqlite3.Xsqlite3_prepare_v2(c.tls, c.db, *zSQL, -1, ppstmt, pptail); rc {
		case sqlite3.SQLITE_OK:
			*zSQL = *(*uintptr)(unsafe.Pointer(pptail))
			return *(*uintptr)(unsafe.Pointer(ppstmt)), nil
		case sqliteLockedSharedcache, sqlite3.SQLITE_BUSY:
cznic's avatar
cznic committed
1050 1051 1052 1053 1054 1055 1056
			if err := c.retry(0); err != nil {
				return 0, err
			}
		default:
			return 0, c.errstr(rc)
		}
	}
cznic's avatar
cznic committed
1057 1058
}

cznic's avatar
cznic committed
1059
// void sqlite3_interrupt(sqlite3*);
cznic's avatar
cznic committed
1060 1061
func (c *conn) interrupt(pdb uintptr) (err error) {
	sqlite3.Xsqlite3_interrupt(c.tls, pdb)
cznic's avatar
cznic committed
1062
	return nil
cznic's avatar
cznic committed
1063 1064
}

cznic's avatar
cznic committed
1065 1066
// int sqlite3_extended_result_codes(sqlite3*, int onoff);
func (c *conn) extendedResultCodes(on bool) error {
cznic's avatar
cznic committed
1067
	if rc := sqlite3.Xsqlite3_extended_result_codes(c.tls, c.db, libc.Bool32(on)); rc != sqlite3.SQLITE_OK {
cznic's avatar
cznic committed
1068 1069 1070 1071
		return c.errstr(rc)
	}

	return nil
cznic's avatar
cznic committed
1072 1073
}

cznic's avatar
cznic committed
1074 1075 1076 1077 1078
// 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 */
cznic's avatar
cznic committed
1079
// );
cznic's avatar
cznic committed
1080 1081
func (c *conn) openV2(name string, flags int32) (uintptr, error) {
	var p, s uintptr
cznic's avatar
cznic committed
1082

cznic's avatar
cznic committed
1083 1084 1085 1086 1087 1088
	defer func() {
		if p != 0 {
			c.free(p)
		}
		if s != 0 {
			c.free(s)
1089 1090 1091
		}
	}()

cznic's avatar
cznic committed
1092
	p, err := c.malloc(int(ptrSize))
cznic's avatar
cznic committed
1093 1094 1095 1096
	if err != nil {
		return 0, err
	}

cznic's avatar
cznic committed
1097
	if s, err = libc.CString(name); err != nil {
cznic's avatar
cznic committed
1098
		return 0, err
cznic's avatar
cznic committed
1099 1100
	}

cznic's avatar
cznic committed
1101
	if rc := sqlite3.Xsqlite3_open_v2(c.tls, s, p, flags, 0); rc != sqlite3.SQLITE_OK {
cznic's avatar
cznic committed
1102 1103
		return 0, c.errstr(rc)
	}
cznic's avatar
cznic committed
1104

cznic's avatar
cznic committed
1105
	return *(*uintptr)(unsafe.Pointer(p)), nil
cznic's avatar
cznic committed
1106 1107
}

cznic's avatar