jm

Odin for scripts: small packages and a runner, on core: only
Log | Files | Refs | README

sqlite3.odin (16557B)


      1 /*
      2 Package sqlite3 is SQLite for scripts. The amalgamation is vendored and linked
      3 statically, so a built script needs no system library and no shared object at
      4 runtime. The README's SQLite section records the version, the compile-time
      5 options and how to check a build for a stray libsqlite3.
      6 
      7 	db := must(sqlite3.open("notes.db"))
      8 	defer sqlite3.close(&db)
      9 
     10 	must(sqlite3.exec(db, `CREATE TABLE IF NOT EXISTS note(id INTEGER PRIMARY KEY, body TEXT)`))
     11 	must(sqlite3.exec_args(db, `INSERT INTO note(body) VALUES (?)`, "it isn't quoted by hand"))
     12 
     13 	rows := must(sqlite3.query(db, `SELECT id, body FROM note WHERE body LIKE ?`, "%isn't%"))
     14 	defer sqlite3.finish(&rows)
     15 	for sqlite3.next(&rows) {
     16 		fmt.println(sqlite3.integer(rows, 0), sqlite3.text(rows, 1))
     17 	}
     18 
     19 Values are always bound, never interpolated into the SQL: a parameter holding
     20 an apostrophe, a newline or a NUL byte round-trips unchanged, and there is no
     21 string-building path for an injection to travel down.
     22 
     23 Memory: text and blob columns are cloned into the allocator the query was
     24 given, because SQLite frees its own copy on the next step. Everything else is
     25 a value.
     26 
     27 Threads: the justfile's `sqlite` recipe sets SQLITE_THREADSAFE=1, which is
     28 SQLite's serialized mode. One Db is not guarded here, so a Db shared across
     29 jm:flow workers needs the caller's own mutex, or a connection per worker.
     30 */
     31 package sqlite3
     32 
     33 import "core:c"
     34 import "core:fmt"
     35 import "core:mem"
     36 import "core:strings"
     37 import "core:time"
     38 
     39 // Code is a SQLite primary result code. Ok, Row and Done are not failures.
     40 Code :: enum i32 {
     41 	Ok         = 0,
     42 	Error      = 1,
     43 	Internal   = 2,
     44 	Perm       = 3,
     45 	Abort      = 4,
     46 	Busy       = 5,
     47 	Locked     = 6,
     48 	No_Mem     = 7,
     49 	Read_Only  = 8,
     50 	Interrupt  = 9,
     51 	Io         = 10,
     52 	Corrupt    = 11,
     53 	Not_Found  = 12,
     54 	Full       = 13,
     55 	Cant_Open  = 14,
     56 	Protocol   = 15,
     57 	Empty      = 16,
     58 	Schema     = 17,
     59 	Too_Big    = 18,
     60 	Constraint = 19,
     61 	Mismatch   = 20,
     62 	Misuse     = 21,
     63 	No_Lfs     = 22,
     64 	Auth       = 23,
     65 	Format     = 24,
     66 	Range      = 25,
     67 	Not_A_Db   = 26,
     68 	Notice     = 27,
     69 	Warning    = 28,
     70 	Row        = 100,
     71 	Done       = 101,
     72 }
     73 
     74 // Fault is a failed call: the result code and the message the connection gave
     75 // for it, which names the constraint or the file rather than restating the
     76 // code. The text is cloned, so it outlives the next call.
     77 Fault :: struct {
     78 	code: Code,
     79 	text: string,
     80 }
     81 
     82 // Error is nil when a call succeeded, so `or_return` and prelude.must both
     83 // work on it.
     84 Error :: union {
     85 	Fault,
     86 }
     87 
     88 // Type is a column's storage class in the row the cursor is on.
     89 Type :: enum {
     90 	Null,
     91 	Integer,
     92 	Real,
     93 	Text,
     94 	Blob,
     95 }
     96 
     97 // Value is one bound parameter. A string binds as TEXT, []byte as BLOB, nil
     98 // as NULL, and bool as the integer 0 or 1, which is how SQLite stores it.
     99 Value :: union {
    100 	i64,
    101 	f64,
    102 	bool,
    103 	string,
    104 	[]byte,
    105 }
    106 
    107 // Db is an open connection.
    108 Db :: struct {
    109 	handle:    ^Connection,
    110 	allocator: mem.Allocator,
    111 }
    112 
    113 // Stmt is one compiled statement, and the row cursor query hands back. The
    114 // column readers below are valid after next has returned true.
    115 Stmt :: struct {
    116 	db:        ^Connection,
    117 	handle:    ^Statement,
    118 	allocator: mem.Allocator,
    119 	// Set when the last step failed, and returned by finish.
    120 	err:       Error,
    121 }
    122 
    123 // Opts tunes how open opens the database.
    124 Opts :: struct {
    125 	// Open an existing database for reading only. Nothing is created.
    126 	read_only:    bool,
    127 	// Do not create the database if it is missing; fail with Cant_Open.
    128 	no_create:    bool,
    129 	// Read path as a file: URI, so query parameters like ?mode=ro apply.
    130 	uri:          bool,
    131 	// Switch the database to write-ahead logging after opening. An in-memory
    132 	// database keeps the mode it had; see the tests for both cases.
    133 	wal:          bool,
    134 	// How long a write blocked by another connection waits before Busy.
    135 	busy_timeout: time.Duration,
    136 	// Run these statements right after opening, before anything else. A
    137 	// pragma the whole connection needs belongs here.
    138 	on_open:      string,
    139 }
    140 
    141 // MEMORY opens a private in-memory database that is discarded on close.
    142 MEMORY :: ":memory:"
    143 
    144 // open opens the database at path, creating it unless Opts says otherwise.
    145 // Pass MEMORY for a scratch database that never touches the disk.
    146 open :: proc(
    147 	path: string,
    148 	opts := Opts{},
    149 	allocator := context.allocator,
    150 ) -> (
    151 	db: Db,
    152 	err: Error,
    153 ) {
    154 	flags := c.int(OPEN_READWRITE | OPEN_CREATE)
    155 	if opts.read_only {
    156 		flags = OPEN_READONLY
    157 	} else if opts.no_create {
    158 		flags = OPEN_READWRITE
    159 	}
    160 	if opts.uri {
    161 		flags |= OPEN_URI
    162 	}
    163 	handle: ^Connection
    164 	name := strings.clone_to_cstring(path, context.temp_allocator)
    165 	code := Code(sqlite3_open_v2(name, &handle, flags, nil))
    166 	if code != .Ok {
    167 		// open_v2 hands back a handle even on failure, so the message can be
    168 		// read off it; closing it is the caller's job, done here.
    169 		err = fault(handle, code, allocator)
    170 		sqlite3_close_v2(handle)
    171 		return {}, err
    172 	}
    173 	db = Db {
    174 		handle    = handle,
    175 		allocator = allocator,
    176 	}
    177 	if opts.busy_timeout > 0 {
    178 		ms := c.int(time.duration_milliseconds(opts.busy_timeout))
    179 		sqlite3_busy_timeout(handle, ms)
    180 	}
    181 	if opts.wal {
    182 		// SQLite refuses WAL for an in-memory database and keeps the mode it
    183 		// had. Nothing else here depends on the mode, so the result is not
    184 		// worth failing the open over.
    185 		_ = exec(db, "PRAGMA journal_mode = WAL")
    186 	}
    187 	if opts.on_open != "" {
    188 		if err = exec(db, opts.on_open); err != nil {
    189 			sqlite3_close_v2(handle)
    190 			return {}, err
    191 		}
    192 	}
    193 	return db, nil
    194 }
    195 
    196 // close closes the connection and zeroes db. An open transaction is rolled
    197 // back. A Stmt that was never finished keeps the connection alive as a
    198 // zombie until it is, so finish every statement before closing: that is what
    199 // sqlite3_close_v2 defers on, and the file stays open until it happens.
    200 close :: proc(db: ^Db) -> Error {
    201 	if db == nil || db.handle == nil {
    202 		return nil
    203 	}
    204 	code := Code(sqlite3_close_v2(db.handle))
    205 	err := code == .Ok ? nil : fault(db.handle, code, db.allocator)
    206 	db^ = {}
    207 	return err
    208 }
    209 
    210 // exec runs sql for its effect and discards any rows. The text may hold
    211 // several statements separated by semicolons, which is what a schema is, and
    212 // each runs in turn. It binds nothing: use exec_args to pass values.
    213 exec :: proc(db: Db, sql: string) -> Error {
    214 	rest := sql
    215 	for {
    216 		stmt, tail, err := prepare_one(db, rest)
    217 		if err != nil {
    218 			return err
    219 		}
    220 		if stmt.handle == nil {
    221 			// Only whitespace or a comment was left.
    222 			return nil
    223 		}
    224 		for {
    225 			code := Code(sqlite3_step(stmt.handle))
    226 			if code == .Row {
    227 				continue
    228 			}
    229 			if code != .Done {
    230 				sqlite3_finalize(stmt.handle)
    231 				return fault(db.handle, code, db.allocator)
    232 			}
    233 			break
    234 		}
    235 		sqlite3_finalize(stmt.handle)
    236 		rest = tail
    237 		if strings.trim_space(rest) == "" {
    238 			return nil
    239 		}
    240 	}
    241 }
    242 
    243 // exec_args runs one statement with args bound to its ? parameters and
    244 // discards any rows. It is the write half of query.
    245 exec_args :: proc(db: Db, sql: string, args: ..Value) -> Error {
    246 	stmt := query(db, sql, ..args) or_return
    247 	for next(&stmt) {}
    248 	return finish(&stmt)
    249 }
    250 
    251 // query compiles sql, binds args to its ? parameters in order, and returns
    252 // the cursor to step with next. Only the first statement in sql is run.
    253 query :: proc(
    254 	db: Db,
    255 	sql: string,
    256 	args: ..Value,
    257 	allocator := context.allocator,
    258 ) -> (
    259 	stmt: Stmt,
    260 	err: Error,
    261 ) {
    262 	stmt, _, err = prepare_one(db, sql, allocator)
    263 	if err != nil {
    264 		return {}, err
    265 	}
    266 	if stmt.handle == nil {
    267 		return {}, Fault{code = .Error, text = strings.clone("no statement in sql", allocator)}
    268 	}
    269 	if err = bind(&stmt, ..args); err != nil {
    270 		sqlite3_finalize(stmt.handle)
    271 		return {}, err
    272 	}
    273 	return stmt, nil
    274 }
    275 
    276 // prepare compiles sql for repeated use: bind, step and reset it, then finish
    277 // it once. Binding one statement many times is how a batch of inserts should
    278 // be written, since the SQL is parsed once.
    279 prepare :: proc(db: Db, sql: string, allocator := context.allocator) -> (stmt: Stmt, err: Error) {
    280 	stmt, _, err = prepare_one(db, sql, allocator)
    281 	if err != nil {
    282 		return {}, err
    283 	}
    284 	if stmt.handle == nil {
    285 		return {}, Fault{code = .Error, text = strings.clone("no statement in sql", allocator)}
    286 	}
    287 	return stmt, nil
    288 }
    289 
    290 // bind sets the statement's parameters, numbered from 1 in the order given.
    291 // Passing a different count than the statement declares is a Range fault,
    292 // caught here rather than leaving a parameter silently NULL.
    293 bind :: proc(stmt: ^Stmt, args: ..Value) -> Error {
    294 	want := int(sqlite3_bind_parameter_count(stmt.handle))
    295 	if want != len(args) {
    296 		return Fault {
    297 			code = .Range,
    298 			text = fmt.aprintf(
    299 				"statement takes %d parameters, got %d",
    300 				want,
    301 				len(args),
    302 				allocator = stmt.allocator,
    303 			),
    304 		}
    305 	}
    306 	for arg, i in args {
    307 		idx := c.int(i + 1)
    308 		code: Code
    309 		switch v in arg {
    310 		case i64:
    311 			code = Code(sqlite3_bind_int64(stmt.handle, idx, v))
    312 		case f64:
    313 			code = Code(sqlite3_bind_double(stmt.handle, idx, v))
    314 		case bool:
    315 			code = Code(sqlite3_bind_int64(stmt.handle, idx, v ? 1 : 0))
    316 		case string:
    317 			// raw_data of an empty string is nil, which binds NULL rather
    318 			// than the empty string, so hand SQLite a valid pointer instead.
    319 			p := len(v) > 0 ? raw_data(v) : ([^]u8)(&empty_byte)
    320 			code = Code(sqlite3_bind_text(stmt.handle, idx, p, c.int(len(v)), TRANSIENT))
    321 		case []byte:
    322 			p := len(v) > 0 ? rawptr(raw_data(v)) : rawptr(&empty_byte)
    323 			code = Code(sqlite3_bind_blob(stmt.handle, idx, p, c.int(len(v)), TRANSIENT))
    324 		case:
    325 			code = Code(sqlite3_bind_null(stmt.handle, idx))
    326 		}
    327 		if code != .Ok {
    328 			return fault(stmt.db, code, stmt.allocator)
    329 		}
    330 	}
    331 	return nil
    332 }
    333 
    334 // next advances to the next row and reports whether one arrived. A failure
    335 // stops the loop and is kept on the statement for finish to return, so the
    336 // common read loop needs no error check of its own.
    337 next :: proc(stmt: ^Stmt) -> bool {
    338 	if stmt.handle == nil || stmt.err != nil {
    339 		return false
    340 	}
    341 	code := Code(sqlite3_step(stmt.handle))
    342 	switch code {
    343 	case .Row:
    344 		return true
    345 	case .Done:
    346 		return false
    347 	case .Ok,
    348 	     .Error,
    349 	     .Internal,
    350 	     .Perm,
    351 	     .Abort,
    352 	     .Busy,
    353 	     .Locked,
    354 	     .No_Mem,
    355 	     .Read_Only,
    356 	     .Interrupt,
    357 	     .Io,
    358 	     .Corrupt,
    359 	     .Not_Found,
    360 	     .Full,
    361 	     .Cant_Open,
    362 	     .Protocol,
    363 	     .Empty,
    364 	     .Schema,
    365 	     .Too_Big,
    366 	     .Constraint,
    367 	     .Mismatch,
    368 	     .Misuse,
    369 	     .No_Lfs,
    370 	     .Auth,
    371 	     .Format,
    372 	     .Range,
    373 	     .Not_A_Db,
    374 	     .Notice,
    375 	     .Warning:
    376 		stmt.err = fault(stmt.db, code, stmt.allocator)
    377 		return false
    378 	}
    379 	return false
    380 }
    381 
    382 // reset rewinds a prepared statement for its next use and clears its
    383 // bindings, so a stale parameter cannot leak into the following row.
    384 reset :: proc(stmt: ^Stmt) -> Error {
    385 	if stmt.handle == nil {
    386 		return nil
    387 	}
    388 	stmt.err = nil
    389 	if code := Code(sqlite3_reset(stmt.handle)); code != .Ok {
    390 		return fault(stmt.db, code, stmt.allocator)
    391 	}
    392 	sqlite3_clear_bindings(stmt.handle)
    393 	return nil
    394 }
    395 
    396 // finish releases the statement and returns whatever failure stopped it.
    397 // Calling it twice is safe.
    398 finish :: proc(stmt: ^Stmt) -> Error {
    399 	if stmt.handle == nil {
    400 		return stmt.err
    401 	}
    402 	err := stmt.err
    403 	code := Code(sqlite3_finalize(stmt.handle))
    404 	if err == nil && code != .Ok {
    405 		err = fault(stmt.db, code, stmt.allocator)
    406 	}
    407 	stmt.handle = nil
    408 	return err
    409 }
    410 
    411 // transact runs body between BEGIN and COMMIT, rolls back if body fails, and
    412 // returns body's error. user is passed through untouched, since Odin has no
    413 // closures to capture it.
    414 transact :: proc(db: Db, body: proc(db: Db, user: rawptr) -> Error, user: rawptr = nil) -> Error {
    415 	exec(db, "BEGIN") or_return
    416 	if err := body(db, user); err != nil {
    417 		// The rollback's own failure would hide why the work failed, so the
    418 		// body's error is the one returned.
    419 		_ = exec(db, "ROLLBACK")
    420 		return err
    421 	}
    422 	return exec(db, "COMMIT")
    423 }
    424 
    425 // column_count reports how many columns the current row has.
    426 column_count :: proc(stmt: Stmt) -> int {
    427 	return int(sqlite3_column_count(stmt.handle))
    428 }
    429 
    430 // name is the column's name in the result set, cloned into the statement's
    431 // allocator.
    432 name :: proc(stmt: Stmt, col: int) -> string {
    433 	n := sqlite3_column_name(stmt.handle, c.int(col))
    434 	return n == nil ? "" : strings.clone_from_cstring(n, stmt.allocator)
    435 }
    436 
    437 // integer reads the column as an integer. A NULL or a non-numeric text reads
    438 // as 0, which is SQLite's own conversion.
    439 integer :: proc(stmt: Stmt, col: int) -> i64 {
    440 	return sqlite3_column_int64(stmt.handle, c.int(col))
    441 }
    442 
    443 // real reads the column as a float.
    444 real :: proc(stmt: Stmt, col: int) -> f64 {
    445 	return sqlite3_column_double(stmt.handle, c.int(col))
    446 }
    447 
    448 // boolean reads the column as a truth value: non-zero is true.
    449 boolean :: proc(stmt: Stmt, col: int) -> bool {
    450 	return sqlite3_column_int64(stmt.handle, c.int(col)) != 0
    451 }
    452 
    453 // text reads the column as a string, cloned into the statement's allocator
    454 // because SQLite frees its copy at the next step.
    455 text :: proc(stmt: Stmt, col: int) -> string {
    456 	n := int(sqlite3_column_bytes(stmt.handle, c.int(col)))
    457 	p := sqlite3_column_text(stmt.handle, c.int(col))
    458 	if p == nil || n == 0 {
    459 		return ""
    460 	}
    461 	return strings.clone(string(p[:n]), stmt.allocator)
    462 }
    463 
    464 // blob reads the column's bytes, cloned into the statement's allocator for
    465 // the same reason text is.
    466 blob :: proc(stmt: Stmt, col: int) -> []byte {
    467 	n := int(sqlite3_column_bytes(stmt.handle, c.int(col)))
    468 	p := sqlite3_column_blob(stmt.handle, c.int(col))
    469 	if p == nil || n == 0 {
    470 		return nil
    471 	}
    472 	out := make([]byte, n, stmt.allocator)
    473 	mem.copy(raw_data(out), p, n)
    474 	return out
    475 }
    476 
    477 // type_of is how SQLite is storing the column in this row. A column has no
    478 // one type in SQLite, so the same column can read back differently row to row.
    479 type_of :: proc(stmt: Stmt, col: int) -> Type {
    480 	switch int(sqlite3_column_type(stmt.handle, c.int(col))) {
    481 	case TYPE_INTEGER:
    482 		return .Integer
    483 	case TYPE_FLOAT:
    484 		return .Real
    485 	case TYPE_TEXT:
    486 		return .Text
    487 	case TYPE_BLOB:
    488 		return .Blob
    489 	case TYPE_NULL:
    490 		return .Null
    491 	}
    492 	return .Null
    493 }
    494 
    495 // is_null reports whether the column holds NULL, which the readers above
    496 // cannot tell apart from 0 or the empty string.
    497 is_null :: proc(stmt: Stmt, col: int) -> bool {
    498 	return type_of(stmt, col) == .Null
    499 }
    500 
    501 // interrupt is sqlite3_interrupt: it asks the connection to abandon what it
    502 // is running, and is the one call here meant to be made from another thread.
    503 // The interrupted call comes back as a Fault with code Interrupt.
    504 //
    505 // It exists because nothing else here bounds how long a statement runs. A
    506 // query that keeps returning rows keeps exec and next busy until it is
    507 // interrupted; jm:sqlite3/fuzz uses this to put a deadline on a case.
    508 interrupt :: proc(db: Db) {
    509 	if db.handle != nil {
    510 		sqlite3_interrupt(db.handle)
    511 	}
    512 }
    513 
    514 // changes is how many rows the last INSERT, UPDATE or DELETE touched.
    515 changes :: proc(db: Db) -> i64 {
    516 	return sqlite3_changes64(db.handle)
    517 }
    518 
    519 // last_id is the rowid the last INSERT on this connection assigned.
    520 last_id :: proc(db: Db) -> i64 {
    521 	return sqlite3_last_insert_rowid(db.handle)
    522 }
    523 
    524 // version is the SQLite version compiled in, such as "3.53.4".
    525 version :: proc() -> string {
    526 	return string(sqlite3_libversion())
    527 }
    528 
    529 // empty_byte backs the pointer handed to bind for an empty string or blob,
    530 // so SQLite sees a valid address with length 0 rather than NULL.
    531 @(private)
    532 empty_byte: u8
    533 
    534 // prepare_one compiles the first statement in sql and returns what followed
    535 // it. A handle of nil with no error means sql held no statement.
    536 @(private)
    537 prepare_one :: proc(
    538 	db: Db,
    539 	sql: string,
    540 	allocator := context.allocator,
    541 ) -> (
    542 	stmt: Stmt,
    543 	tail: string,
    544 	err: Error,
    545 ) {
    546 	stmt = Stmt {
    547 		db        = db.handle,
    548 		allocator = allocator,
    549 	}
    550 	if len(sql) == 0 {
    551 		return stmt, "", nil
    552 	}
    553 	rest: [^]u8
    554 	code := Code(
    555 		sqlite3_prepare_v2(db.handle, raw_data(sql), c.int(len(sql)), &stmt.handle, &rest),
    556 	)
    557 	if code != .Ok {
    558 		return {}, "", fault(db.handle, code, allocator)
    559 	}
    560 	if rest != nil {
    561 		// rest points inside sql, so the remainder is the slice from there to
    562 		// the end rather than a new string.
    563 		used := int(uintptr(rest) - uintptr(raw_data(sql)))
    564 		tail = sql[used:]
    565 	}
    566 	return stmt, tail, nil
    567 }
    568 
    569 // fault builds the error for code, preferring the connection's message over
    570 // the generic text for the code.
    571 @(private)
    572 fault :: proc(db: ^Connection, code: Code, allocator: mem.Allocator) -> Error {
    573 	msg: cstring
    574 	if db != nil {
    575 		msg = sqlite3_errmsg(db)
    576 	}
    577 	if msg == nil {
    578 		msg = sqlite3_errstr(c.int(code))
    579 	}
    580 	text := msg == nil ? "" : strings.clone_from_cstring(msg, allocator)
    581 	return Fault{code = code, text = text}
    582 }