43static naRef
f_open(naContext c, naRef me,
int argc, naRef* args)
46 if(argc < 1 || !naIsString(args[0]))
47 naRuntimeError(c,
"Bad/missing argument to sqlite.open");
50 const auto path = SGPath::fromUtf8(naStr_data(args[0]));
51 const SGPath filename = SGPath(path).validate(
true);
52 if (filename.isNull()) {
53 SG_LOG(SG_NASAL, SG_ALERT,
"stat(): reading '" <<
54 naStr_data(args[0]) <<
"' denied (unauthorized directory - authorization"
55 " no longer follows symlinks; to authorize reading additional "
56 "directories, pass them to --allow-nasal-read)");
57 naRuntimeError(c,
"stat(): access denied (unauthorized directory)");
61 int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
62 std::string pathUtf8 = path.utf8Str();
63 if(sqlite3_open_v2(pathUtf8.c_str(), &g->db, openFlags, NULL))
65 const char* msg = sqlite3_errmsg(g->db);
66 sqlite3_close_v2(g->db);
68 naRuntimeError(c,
"sqlite open error: %s", msg);
70 sqlite3_busy_timeout(g->db, 60*60*1000);
71 return naNewGhost(c, &
DBType, g);
83static naRef
f_prepare(naContext c, naRef me,
int argc, naRef* args)
85 naRef
db = argc > 0 ? args[0] : naNil();
86 naRef s = argc > 1 ? args[1] : naNil();
90 if(!naIsString(s) || !dbg)
91 naRuntimeError(c,
"bad/missing argument to sqlite.prepare");
93 if(sqlite3_prepare(dbg->
db, naStr_data(s), naStr_len(s), &g->stmt, &tail))
95 const char* msg = sqlite3_errmsg(dbg->
db);
96 if(g->stmt) sqlite3_finalize(g->stmt);
98 naRuntimeError(c,
"sqlite prepare error: %s", msg);
105static naRef
run_query(naContext c, sqlite3*
db, sqlite3_stmt* stmt,
108 naContext subc = naIsNil(callback) ? 0 : naSubContext(c);
110 naRef val, row, result = subc ? naNil() : naNewVector(c);
112 while((stat = sqlite3_step(stmt)) != SQLITE_DONE) {
113 if(stat != SQLITE_ROW)
114 naRuntimeError(c,
"sqlite step error: %s", sqlite3_errmsg(
db));
116 cols = sqlite3_column_count(stmt);
117 fields = (naRef*)malloc(cols *
sizeof(naRef));
118 for(
i=0;
i<cols;
i++) {
119 const char* s = sqlite3_column_name(stmt,
i);
120 naRef fn = naStr_fromdata(naNewString(c), (
char*)s, strlen(s));
122 fields[
i] = naInternSymbol(fn);
126 for(
i=0;
i<cols;
i++) {
127 int type = sqlite3_column_type(stmt,
i);
128 if(type == SQLITE_BLOB || type == SQLITE_TEXT)
129 val = naStr_fromdata(naNewString(c),
130 (
char*)sqlite3_column_blob(stmt,
i),
131 sqlite3_column_bytes(stmt,
i));
133 val = naNum(sqlite3_column_double(stmt,
i));
134 naHash_set(row, fields[
i], val);
137 naVec_append(result, row);
139 naCall(subc, callback, 1, &row, naNil(), naNil());
140 if(naGetError(subc)) naRethrowError(subc);
143 if(subc) naFreeContext(subc);
148static naRef
f_exec(naContext c, naRef me,
int argc, naRef* args)
150 naRef callback = naNil();
151 naRef
db = argc > 0 ? args[0] : naNil();
152 naRef stmt = argc > 1 ? args[1] : naNil();
154 if(naIsString(stmt)) {
155 naRef args[2]; args[0] =
db; args[1] = stmt;
159 naRuntimeError(c,
"bad/missing argument to sqlite.exec");
160 if(argc > bindings && naIsFunc(args[bindings]))
161 callback = args[bindings++];
162 sqlite3_reset(
STMTG(stmt)->stmt);
163 for(
i=bindings;
i<argc;
i++) {
164 int err=0, bidx=
i-bindings+1;
165 if(naIsString(args[
i]))
166 err = sqlite3_bind_text(
STMTG(stmt)->stmt, bidx,
168 naStr_len(args[
i]), SQLITE_TRANSIENT);
169 else if(naIsNum(args[
i]))
170 err = sqlite3_bind_double(
STMTG(stmt)->stmt, bidx, args[
i].num);
172 naRuntimeError(c,
"sqlite.exec cannot bind non-scalar");
174 naRuntimeError(c,
"sqlite bind error: %s",