building
[libxsql.git] / src / fmtjson.c
blob8a264d485101165aa7922a8a8ac9b781e629099f
1 #include "fmt.h"
3 typedef struct {
4 str_t *name;
5 str_t *fname;
6 xsql_fmtprov_t *prov;
7 int flags;
8 int fd;
9 str_t *str;
10 int is_first;
11 } xsql_json_t;
13 static const char *json_fmtname () {
14 return "json";
17 static xsql_fmt_t *json_open (xsql_fmtprov_t *prov, const char *fname, size_t fname_len, const char *name, size_t name_len, int flags) {
18 xsql_json_t *ret = calloc(1, sizeof(xsql_json_t));
19 ret->name = mkstr(name, name_len, 8);
20 ret->fname = prov->fmtwrtname(fname, fname_len);
21 ret->prov = prov;
22 ret->flags = flags;
23 if (-1 == prov->fmtwrtopen((xsql_fmt_t*)ret)) {
24 if (ret->fname) free(ret->fname);
25 free(ret);
26 return NULL;
28 if (XSQL_WRITE == ret->flags)
29 ret->prov->fmtwrtstr((xsql_fmt_t*)ret, CONST_STR_LEN("["), 0);
30 return (xsql_fmt_t*)ret;
33 static void add_result (xsql_json_t *json, xsql_stmt_t *stmt, int is_comma, str_t **str) {
34 char *s = stmt->result[0];
35 (*str)->len = 0;
36 if (is_comma)
37 strnadd(str, CONST_STR_LEN(","));
38 if (s) {
39 strnadd(str, CONST_STR_LEN("[\""));
40 strnadd(str, s, strlen(s));
41 strnadd(str, CONST_STR_LEN("\""));
42 } else
43 strnadd(str, CONST_STR_LEN("[null"));
44 for (int i = 1; i < stmt->nflds; ++i) {
45 s = stmt->result[i];
46 if (s) {
47 strnadd(str, CONST_STR_LEN(",\""));
48 strnadd(str, s, strlen(s));
49 strnadd(str, CONST_STR_LEN("\""));
50 } else
51 strnadd(str, CONST_STR_LEN(",null"));
53 strnadd(str, CONST_STR_LEN("]"));
56 static void json_start_outrec (xsql_fmt_t *fmt, xsql_stmt_t *stmt) {
57 xsql_json_t *json = (xsql_json_t*)fmt;
58 xsql_fmtprov_t *prov = fmt->prov;
59 str_t *fldnam = stmt->fldnams[0];
60 if (json->str) {
61 json->str->len = 0;
62 strnadd(&json->str, CONST_STR_LEN(","));
63 } else
64 json->str = stralloc(512, 256);
65 // strnadd(&json->str, CONST_STR_LEN("{\"result\":{\"header\":[\""));
66 strnadd(&json->str, CONST_STR_LEN("{\"header\":[\""));
67 strnadd(&json->str, fldnam->ptr, fldnam->len);
68 strnadd(&json->str, CONST_STR_LEN("\""));
69 for (int i = 1; i < stmt->nflds; ++i) {
70 fldnam = stmt->fldnams[i];
71 strnadd(&json->str, CONST_STR_LEN(",\""));
72 strnadd(&json->str, fldnam->ptr, fldnam->len);
73 strnadd(&json->str, CONST_STR_LEN("\""));
75 strnadd(&json->str, CONST_STR_LEN("],\"data\":["));
76 prov->fmtwrtstr(fmt, json->str->ptr, json->str->len, 0);
77 // add_result(json, stmt, 0, &json->str);
78 // prov->fmtwrtstr(fmt, json->str->ptr, json->str->len, 0);
81 static void json_outrec (xsql_fmt_t *fmt, xsql_stmt_t *stmt) {
82 xsql_json_t *json = (xsql_json_t*)fmt;
83 add_result(json, stmt, 1, &json->str);
84 fmt->prov->fmtwrtstr(fmt, json->str->ptr, json->str->len, 0);
87 static void json_end_outrec (xsql_fmt_t *fmt, xsql_stmt_t *stmt) {
88 //fmt->prov->fmtwrtstr(fmt, CONST_STR_LEN("]}}"), 0);
89 fmt->prov->fmtwrtstr(fmt, CONST_STR_LEN("]}"), 0);
92 static void json_start_outvar (xsql_fmt_t *fmt) {
93 xsql_json_t *json = (xsql_json_t*)fmt;
94 if (json->str) {
95 json->str->len = 0;
96 strnadd(&json->str, CONST_STR_LEN(","));
97 } else
98 json->str = stralloc(512, 256);
99 strnadd(&json->str, CONST_STR_LEN("["));
100 json->is_first = 1;
103 static void json_outvar (xsql_fmt_t *fmt, xsql_var_t *var, size_t index) {
104 xsql_json_t *json = (xsql_json_t*)fmt;
105 strptr_t str;
106 if (!json->is_first)
107 strnadd(&json->str, CONST_STR_LEN(","));
108 json->is_first = 0;
109 if (var->typ == TYP_STRING) {
110 str.ptr = var->raw.s_val->ptr;
111 str.len = var->raw.s_val->len;
112 } else {
113 const char *s = xsql_varstr(var);
114 str.ptr = (char*)s;
115 str.len = strlen(s);
117 strnadd(&json->str, CONST_STR_LEN("\""));
118 strnadd(&json->str, str.ptr, str.len);
119 strnadd(&json->str, CONST_STR_LEN("\""));
120 // fmt->prov->fmtwrtstr(fmt, json->str->ptr, json->str->len, 0);
121 // json->str->len = 0;
124 static void json_end_outvar (xsql_fmt_t *fmt) {
125 xsql_json_t *json = (xsql_json_t*)fmt;
126 strnadd(&json->str, CONST_STR_LEN("]"));
127 // fmt->prov->fmtwrtstr(fmt, CONST_STR_LEN("]"), 0);
128 fmt->prov->fmtwrtstr(fmt, json->str->ptr, json->str->len, 0);
129 json->str->len = 0;
132 static void json_plot (xsql_fmt_t *fmt, const char *fname, size_t fname_len) {
133 str_t *buf = load_all_file(fname, 8, 0);
134 if (!buf) return;
135 xsql_json_t *json = (xsql_json_t*)fmt;
136 if (json->str) {
137 json->str->len = 0;
138 strnadd(&json->str, CONST_STR_LEN(","));
139 } else
140 json->str = stralloc(buf->len > 512 ? buf->len : 512, 256);
141 strnadd(&json->str, CONST_STR_LEN("{\"image\":\""));
142 fmt->prov->fmtwrtstr(fmt, json->str->ptr, json->str->len, 0);
143 str_t *edata = str_base64_encode(buf->ptr, buf->len, 256);
144 strnadd(&edata, CONST_STR_LEN("\"}"));
145 fmt->prov->fmtwrtstr(fmt, edata->ptr, edata->len, 0);
146 free(edata);
147 free(buf);
150 static void json_close (xsql_fmt_t *fmt) {
151 xsql_json_t *json = (xsql_json_t*)fmt;
152 if (XSQL_WRITE == fmt->flags)
153 fmt->prov->fmtwrtstr(fmt, CONST_STR_LEN("]"), 0);
154 if (json->str) free(json->str);
155 if (json->fname) free(json->fname);
156 if (json->name) free(json->name);
157 if (json->fd > 0) close(json->fd);
158 free(json);
161 xsql_fmtprov_t *xsql_create_json_provider () {
162 xsql_fmtprov_t *ret = calloc(1, sizeof(xsql_fmtprov_t));
163 ret->hnd = 0;
164 ret->fmtname = json_fmtname;
165 ret->fmtwrtname = file_wrtname;
166 ret->fmtopen = json_open;
167 ret->fmtwrtopen = file_wrtopen;
168 ret->fmtstart_outrec = json_start_outrec;
169 ret->fmtoutrec = json_outrec;
170 ret->fmtend_outrec = json_end_outrec;
171 ret->fmtstart_outvar = json_start_outvar;
172 ret->fmtwrtvar = file_wrtvar;
173 ret->fmtwrtstr = file_wrtstr;
174 ret->fmtoutvar = json_outvar;
175 ret->fmtend_outvar = json_end_outvar;
176 ret->fmtwrtend = file_wrtend;
177 ret->fmtclose = json_close;
178 ret->fmtwrtclose = file_wrtclose;
179 ret->fmtend = NULL;
180 ret->fmtnewtab = NULL;
181 ret->fmtplot = json_plot;
182 return ret;