#ifndef BOKF_CMD_UTIL_H #define BOKF_CMD_UTIL_H #include #include #include #include "commands.h" #include "protocol.h" #include "yyjson.h" const char *sq(const unsigned char *p); const char *arg_str(yyjson_val *args, const char *key); int arg_int(yyjson_val *args, const char *key, int64_t *out); int arg_bool(yyjson_val *args, const char *key, int *out); const char *arg_type_name(enum arg_type type); int enum_allowed(const char *values, const char *v); void arg_error(char *err, size_t errlen, const char *fmt, ...) __attribute__((format(printf, 3, 4))); int command_validate_args(const struct command *cmd, yyjson_val *args, char *err, size_t errlen); yyjson_mut_val *fail(struct req *r, const char *code, const char *msg); yyjson_mut_val *failf(struct req *r, const char *code, const char *fmt, ...) __attribute__((format(printf, 3, 4))); yyjson_mut_val *db_error(struct req *r); yyjson_mut_val *db_sqlite_error(struct req *r); void bind_text_or_null(sqlite3_stmt *st, int idx, const char *s); /* spec: "id:i,name:s,active:b" — i int, s text ("" for NULL), b bool, * n nullable text (JSON null for NULL), r nullable int; columns from 0. */ yyjson_mut_val *db_row_json(yyjson_mut_doc *doc, sqlite3_stmt *st, const char *spec); /* types: one letter per bind — i int64_t, s const char *, n nullable * const char *. Returns the statement bound at ?1.., NULL on prepare error. */ sqlite3_stmt *db_prepare_bound(sqlite3 *db, const char *sql, const char *types, ...); /* 0 on SQLITE_DONE, -1 when prepare fails, else the step result. */ int db_exec_bound(sqlite3 *db, const char *sql, const char *types, ...); /* db_exec_bound with the request's error set: db_error on prepare failure, * db_sqlite_error on any other step result. Returns 0 on success. */ int req_exec(struct req *r, const char *sql, const char *types, ...); /* {"items":[db_row_json(spec) per row]} for a bound SELECT; NULL with * db_error set when prepare fails. */ yyjson_mut_val *req_list(struct req *r, const char *sql, const char *spec, const char *types, ...); int mkdir_p(const char *path, mode_t mode); yyjson_mut_val *json_to_mut(yyjson_mut_doc *doc, const char *json); int is_digits(const char *s); int64_t default_fy_id(sqlite3 *db, int64_t org_id); int req_fy(struct req *r, int64_t *out); unsigned char *read_file(const char *path, size_t *out_len); struct tpl_head { int64_t id; char name[128]; char series[16]; char description[256]; }; struct tpl_loaded { char account[16]; char formula[256]; char desc[128]; }; double parse_kr_double(const char *s, int *ok); char *replace_x(const char *text, double x); int load_template(sqlite3 *db, int64_t org_id, int64_t id, const char *name, struct tpl_head *head, char **err); int load_template_rows(sqlite3 *db, int64_t org_id, int64_t tpl, struct tpl_loaded **out, size_t *out_n, char **err); #endif