Fun 0.41.5
The programming language that makes you have fun!
Loading...
Searching...
No Matches
query.c
Go to the documentation of this file.
1/*
2 * This file is part of the Fun programming language.
3 * https://fun-lang.xyz/
4 *
5 * Copyright 2025 Johannes Findeisen <you@hanez.org>
6 * Licensed under the terms of the Apache-2.0 license.
7 * https://opensource.org/license/apache-2-0
8 */
9
10/**
11 * @file query.c
12 * @brief Implements the OP_SQLITE_QUERY opcode (conditional build).
13 *
14 * Prepares and steps through a SQLite statement to produce an array of row
15 * maps when FUN_WITH_SQLITE is enabled. Returns an empty array otherwise.
16 *
17 * OP_SQLITE_QUERY: (handle:int, sql:string) -> array<map<string,any>>
18 */
19
21#ifdef FUN_WITH_SQLITE
22 Value vsql = pop_value(vm);
24 int hid = (int)vh.i;
25 char *sql = value_to_string_alloc(&vsql);
29 if (!h || !h->db || !sql) {
30 if (sql) free(sql);
32 break;
33 }
34 sqlite3_stmt *stmt = NULL;
35 if (sqlite3_prepare_v2(h->db, sql, -1, &stmt, NULL) != SQLITE_OK) {
36 free(sql);
38 break;
39 }
42 int ncols = sqlite3_column_count(stmt);
43 while (sqlite3_step(stmt) == SQLITE_ROW) {
44 Value row = make_map_empty();
45 for (int i = 0; i < ncols; i++) {
46 const char *name = sqlite3_column_name(stmt, i);
47 int type = sqlite3_column_type(stmt, i);
48 Value kv;
49 switch (type) {
50 case SQLITE_INTEGER:
51 kv = make_int((int64_t)sqlite3_column_int64(stmt, i));
52 break;
53 case SQLITE_FLOAT:
54 kv = make_float(sqlite3_column_double(stmt, i));
55 break;
56 case SQLITE_TEXT:
57 kv = make_string((const char *)sqlite3_column_text(stmt, i));
58 break;
59 case SQLITE_NULL:
60 kv = make_nil();
61 break;
62 default:
63 kv = make_nil();
64 break; /* ignore blobs for now */
65 }
66 (void)map_set(&row, name ? name : "", kv);
67 }
68 (void)array_push(&rows, row);
69 /* Do NOT free 'row' here: rows array now owns it. Freeing would
70 destroy the map and leave a dangling pointer causing segfaults
71 when accessing fields like row["done"]. */
72 }
75#else
76 Value v1 = pop_value(vm);
77 free_value(v1);
78 Value v2 = pop_value(vm);
79 free_value(v2);
81#endif
82 break;
83}
@ OP_SQLITE_QUERY
Definition bytecode.h:181
int hid
Definition disconnect.c:33
CURL * h
Definition download.c:59
const char * name
Definition env.c:29
char * sql
Definition exec.c:25
Value vh
Definition get_bool.c:38
int map_set(Value *vm, const char *key, Value v)
Insert or replace a key in the map.
Definition map.c:79
Value make_map_empty(void)
Construct a new empty map Value.
Definition map.c:35
free(sql)
Value rows
Definition query.c:41
free_value(vh)
sqlite3_stmt * stmt
Definition query.c:34
int ncols
Definition query.c:42
sqlite3_finalize(stmt)
push_value(vm, rows)
static SqlHandle * sql_reg_get(int id)
Look up a registered SQLite handle by id.
Definition sqlite.c:70
Node in a singly-linked list of registered SQLite handles.
Definition sqlite.c:29
Tagged union representing a Fun value.
Definition value.h:68
Value make_nil(void)
Construct a nil Value.
Definition value.c:126
Value make_string(const char *s)
Construct a string Value by duplicating the given C string.
Definition value.c:95
char * value_to_string_alloc(const Value *v)
Allocate a printable C string for a Value.
Definition value.c:641
Value make_float(double v)
Construct a Value representing a double-precision float.
Definition value.c:64
int array_push(Value *v, Value newElem)
Append a Value to an array.
Definition value.c:257
Value make_int(int64_t v)
Construct a Value representing a 64-bit integer.
Definition value.c:51
Value make_array_from_values(const Value *vals, int count)
Create an array Value by copying items from an input span.
Definition value.c:142
static Value pop_value(VM *vm)
Pop a Value from the VM operand stack.
Definition vm.c:580