Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "stream.h"
15 : #include "mapi.h"
16 : #include "monetdbe_mapi.h"
17 : #include "mal_exception.h"
18 :
19 : #define MAPIalloc(sz) malloc(sz)
20 : #define MAPIfree(p) free(p)
21 :
22 : monetdbe_MapiMsg
23 0 : monetdbe_mapi_error(monetdbe_Mapi mid)
24 : {
25 0 : if (mid->msg)
26 0 : return MERROR;
27 : return MOK;
28 : }
29 :
30 : monetdbe_MapiHdl
31 0 : monetdbe_mapi_query(monetdbe_Mapi mid, const char *query)
32 : {
33 0 : monetdbe_MapiHdl mh = (monetdbe_MapiHdl)MAPIalloc(sizeof(struct monetdbe_MapiStatement));
34 :
35 0 : if (!mh)
36 : return NULL;
37 0 : mh->mid = mid;
38 0 : mh->query = (char*)query;
39 0 : mh->msg = monetdbe_query(mh->mid->mdbe, mh->query, &mh->result, &mh->affected_rows);
40 0 : mh->current_row = 0;
41 0 : mh->mapi_row = NULL;
42 0 : if (mh->result && mh->result->ncols) {
43 0 : mh->mapi_row = (char**)MAPIalloc(sizeof(char*)*mh->result->ncols);
44 0 : if (!mh->mapi_row) {
45 0 : mh->msg = "malloc failure";
46 0 : return mh;
47 : }
48 0 : memset(mh->mapi_row, 0, sizeof(char*)*mh->result->ncols);
49 : }
50 : return mh;
51 : }
52 :
53 : monetdbe_MapiMsg
54 0 : monetdbe_mapi_close_handle(monetdbe_MapiHdl hdl)
55 : {
56 0 : if (hdl) {
57 0 : char *msg = NULL;
58 0 : if (hdl->result) {
59 0 : if (hdl->mapi_row) {
60 0 : for (size_t i=0; i<hdl->result->ncols; i++) {
61 0 : if (hdl->mapi_row[i])
62 0 : MAPIfree(hdl->mapi_row[i]);
63 : }
64 0 : MAPIfree(hdl->mapi_row);
65 : }
66 0 : msg = monetdbe_cleanup_result(hdl->mid->mdbe, hdl->result);
67 0 : if (msg)
68 0 : hdl->mid->msg = msg;
69 : }
70 0 : MAPIfree(hdl);
71 : }
72 0 : return MOK;
73 : }
74 :
75 : int
76 0 : monetdbe_mapi_fetch_row(monetdbe_MapiHdl hdl)
77 : {
78 0 : int n = 0;
79 :
80 0 : if (hdl->result && hdl->current_row < hdl->result->nrows) {
81 0 : n = (int) ++hdl->current_row;
82 : }
83 0 : return n;
84 : }
85 :
86 : #define SIMPLE_TYPE_SIZE 128
87 :
88 : char *
89 0 : monetdbe_mapi_fetch_field(monetdbe_MapiHdl hdl, int fnr)
90 : {
91 0 : if (fnr < (int)hdl->result->ncols && hdl->current_row > 0 && hdl->current_row <= hdl->result->nrows) {
92 0 : monetdbe_column *rcol = NULL;
93 0 : if (monetdbe_result_fetch(hdl->result, &rcol, fnr) == NULL) {
94 0 : size_t r = (size_t) hdl->current_row - 1;
95 0 : if (rcol->type != monetdbe_str && !hdl->mapi_row[fnr]) {
96 0 : hdl->mapi_row[fnr] = MAPIalloc(SIMPLE_TYPE_SIZE);
97 0 : if (!hdl->mapi_row[fnr]) {
98 0 : hdl->msg = "malloc failure";
99 0 : return NULL;
100 : }
101 : }
102 0 : switch(rcol->type) {
103 0 : case monetdbe_bool: {
104 0 : monetdbe_column_bool *icol = (monetdbe_column_bool*)rcol;
105 0 : if (icol->data[r] == icol->null_value)
106 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "NULL");
107 : else
108 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "%s", icol->data[r]==1?"true":"false");
109 0 : return hdl->mapi_row[fnr];
110 : }
111 0 : case monetdbe_int8_t: {
112 0 : monetdbe_column_int8_t *icol = (monetdbe_column_int8_t*)rcol;
113 0 : if (icol->data[r] == icol->null_value)
114 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "NULL");
115 : else
116 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "%d", icol->data[r]);
117 0 : return hdl->mapi_row[fnr];
118 : }
119 0 : case monetdbe_int16_t: {
120 0 : monetdbe_column_int16_t *icol = (monetdbe_column_int16_t*)rcol;
121 0 : if (icol->data[r] == icol->null_value)
122 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "NULL");
123 : else
124 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "%d", icol->data[r]);
125 0 : return hdl->mapi_row[fnr];
126 : }
127 0 : case monetdbe_int32_t: {
128 0 : monetdbe_column_int32_t *icol = (monetdbe_column_int32_t*)rcol;
129 0 : if (icol->data[r] == icol->null_value)
130 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "NULL");
131 : else
132 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "%d", icol->data[r]);
133 0 : return hdl->mapi_row[fnr];
134 : }
135 0 : case monetdbe_int64_t: {
136 0 : monetdbe_column_int64_t *icol = (monetdbe_column_int64_t*)rcol;
137 0 : if (icol->data[r] == icol->null_value)
138 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "NULL");
139 : else
140 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "%" PRId64, icol->data[r]);
141 0 : return hdl->mapi_row[fnr];
142 : }
143 : #ifdef HAVE_HGE
144 0 : case monetdbe_int128_t: {
145 0 : monetdbe_column_int128_t *icol = (monetdbe_column_int128_t*)rcol;
146 0 : if (icol->data[r] == icol->null_value)
147 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "NULL");
148 : else
149 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "%" PRId64, (int64_t)icol->data[r]);
150 0 : return hdl->mapi_row[fnr];
151 : }
152 : #endif
153 0 : case monetdbe_float: {
154 0 : monetdbe_column_float *icol = (monetdbe_column_float*)rcol;
155 0 : if (icol->data[r] == icol->null_value)
156 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "NULL");
157 : else
158 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "%f", icol->data[r]);
159 0 : return hdl->mapi_row[fnr];
160 : }
161 0 : case monetdbe_double: {
162 0 : monetdbe_column_double *icol = (monetdbe_column_double*)rcol;
163 0 : if (icol->data[r] == icol->null_value)
164 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "NULL");
165 : else
166 0 : snprintf(hdl->mapi_row[fnr], SIMPLE_TYPE_SIZE, "%f", icol->data[r]);
167 0 : return hdl->mapi_row[fnr];
168 : }
169 0 : case monetdbe_str: {
170 0 : monetdbe_column_str *icol = (monetdbe_column_str*)rcol;
171 0 : return icol->data[r];
172 : }
173 : default:
174 : return NULL;
175 : }
176 : }
177 : }
178 : return NULL;
179 : }
180 :
181 : char *
182 0 : monetdbe_mapi_get_type(monetdbe_MapiHdl hdl, int fnr)
183 : {
184 0 : if (fnr < (int)hdl->result->ncols) {
185 0 : monetdbe_column *rcol = NULL;
186 0 : if (monetdbe_result_fetch(hdl->result, &rcol, fnr) == NULL) {
187 0 : switch(rcol->type) {
188 : case monetdbe_bool:
189 0 : return "boolean";
190 0 : case monetdbe_int8_t:
191 0 : return "tinyint";
192 0 : case monetdbe_int16_t:
193 0 : return "smallint";
194 0 : case monetdbe_int32_t:
195 0 : return "integer";
196 0 : case monetdbe_int64_t:
197 0 : return "bigint";
198 : #ifdef HAVE_HGE
199 0 : case monetdbe_int128_t:
200 0 : return "hugeint";
201 : #endif
202 0 : case monetdbe_float:
203 0 : return "float";
204 0 : case monetdbe_double:
205 0 : return "real";
206 0 : case monetdbe_str:
207 0 : return "varchar";
208 0 : default:
209 0 : return "unknown";
210 : }
211 : }
212 : }
213 : return NULL;
214 : }
215 :
216 : monetdbe_MapiMsg
217 0 : monetdbe_mapi_seek_row(monetdbe_MapiHdl hdl, int64_t rowne, int whence)
218 : {
219 0 : if (rowne == 0 && whence == MAPI_SEEK_SET) {
220 0 : hdl->current_row = 0;
221 : }
222 0 : return MOK;
223 : }
224 :
225 : int64_t
226 0 : monetdbe_mapi_get_row_count(monetdbe_MapiHdl hdl)
227 : {
228 0 : return hdl->result->nrows;
229 : }
230 :
231 : int64_t
232 0 : monetdbe_mapi_rows_affected(monetdbe_MapiHdl hdl)
233 : {
234 0 : if (hdl->result)
235 0 : return hdl->result->nrows;
236 0 : return hdl->affected_rows;
237 : }
238 :
239 : int
240 0 : monetdbe_mapi_get_field_count(monetdbe_MapiHdl hdl)
241 : {
242 0 : return (int) hdl->result->ncols;
243 : }
244 :
245 : const char *
246 0 : monetdbe_mapi_result_error(monetdbe_MapiHdl hdl)
247 : {
248 0 : if (hdl) {
249 0 : return hdl->msg;
250 : }
251 : return NULL;
252 : }
253 :
254 0 : int monetdbe_mapi_get_len(monetdbe_MapiHdl hdl, int fnr)
255 : {
256 0 : (void)hdl;
257 0 : (void)fnr;
258 0 : return 0;
259 : }
260 :
261 : /* implement these to make dump.c error's more informative */
262 0 : void monetdbe_mapi_explain(monetdbe_Mapi mid, FILE *fd)
263 : {
264 0 : (void)mid;
265 0 : (void)fd;
266 0 : }
267 :
268 0 : void monetdbe_mapi_explain_query(monetdbe_MapiHdl hdl, FILE *fd)
269 : {
270 0 : (void)hdl;
271 0 : (void)fd;
272 0 : }
273 :
274 0 : void monetdbe_mapi_explain_result(monetdbe_MapiHdl hdl, FILE *fd)
275 : {
276 0 : (void)hdl;
277 0 : (void)fd;
278 0 : }
279 :
280 : #define Mapi monetdbe_Mapi
281 : #define MapiHdl monetdbe_MapiHdl
282 : #define MapiHdl monetdbe_MapiHdl
283 : #define MapiMsg monetdbe_MapiMsg
284 :
285 : #include "msqldump.h"
286 :
287 : char*
288 0 : monetdbe_mapi_dump_database(monetdbe_database dbhdl, const char *filename)
289 : {
290 0 : char* msg = NULL;
291 0 : struct monetdbe_MapiStruct mid = { .mdbe = dbhdl };
292 :
293 : /* open file stream */
294 0 : stream *fd = open_wastream(filename);
295 0 : if (fd) {
296 0 : if (dump_database(&mid, fd, 0, 0, false)) {
297 0 : if (mid.msg)
298 0 : msg = mid.msg;
299 : }
300 0 : close_stream(fd);
301 : } else {
302 0 : return createException(MAL, "embedded.monetdbe_dump_database", "Unable to open file %s: %s", filename, mnstr_peek_error(NULL));
303 : }
304 0 : return msg;
305 : }
306 :
307 : char*
308 0 : monetdbe_mapi_dump_table(monetdbe_database dbhdl, const char *sname, const char *tname, const char *filename)
309 : {
310 0 : char* msg = NULL;
311 0 : struct monetdbe_MapiStruct mid = { .mdbe = dbhdl };
312 :
313 : /* open file stream */
314 0 : stream *fd = open_wastream(filename);
315 0 : if (fd) {
316 0 : if (dump_table(&mid, sname, tname, fd, false, false, false, false, false)) {
317 0 : if (mid.msg)
318 0 : msg = mid.msg;
319 : }
320 0 : close_stream(fd);
321 : } else {
322 0 : return createException(MAL, "embedded.monetdbe_dump_table", "Unable to open file %s: %s", filename, mnstr_peek_error(NULL));
323 : }
324 0 : return msg;
325 : }
|