1 /******************** tabjson H Declares Source Code File (.H) *******************/ 2 /* Name: jsonudf.h Version 1.4 */ 3 /* */ 4 /* (C) Copyright to the author Olivier BERTRAND 2015-2020 */ 5 /* */ 6 /* This file contains the JSON UDF function and class declares. */ 7 /*********************************************************************************/ 8 #pragma once 9 #include "global.h" 10 #include "plgdbsem.h" 11 #include "block.h" 12 #include "osutil.h" 13 #include "maputil.h" 14 #include "json.h" 15 16 #define UDF_EXEC_ARGS \ 17 UDF_INIT*, UDF_ARGS*, char*, unsigned long*, char*, char* 18 19 // BSON size should be equal on Linux and Windows 20 #define BMX 255 21 typedef struct BSON* PBSON; 22 23 /***********************************************************************/ 24 /* Structure used to return binary json to Json UDF functions. */ 25 /***********************************************************************/ 26 struct BSON { 27 char Msg[BMX + 1]; 28 char *Filename; 29 PGLOBAL G; 30 int Pretty; 31 ulong Reslen; 32 my_bool Changed; 33 PJSON Top; 34 PJSON Jsp; 35 PBSON Bsp; 36 }; // end of struct BSON 37 38 PBSON JbinAlloc(PGLOBAL g, UDF_ARGS* args, ulong len, PJSON jsp); 39 40 /*********************************************************************************/ 41 /* The JSON tree node. Can be an Object or an Array. */ 42 /*********************************************************************************/ 43 typedef struct _jnode { 44 PSZ Key; // The key used for object 45 OPVAL Op; // Operator used for this node 46 PVAL CncVal; // To cont value used for OP_CNC 47 int Rank; // The rank in array 48 int Rx; // Read row number 49 int Nx; // Next to read row number 50 } JNODE, *PJNODE; 51 52 typedef class JSNX *PJSNX; 53 54 /*********************************************************************************/ 55 /* The JSON utility functions. */ 56 /*********************************************************************************/ 57 bool IsNum(PSZ s); 58 char *NextChr(PSZ s, char sep); 59 char *GetJsonNull(void); 60 uint GetJsonGrpSize(void); 61 my_bool JsonSubSet(PGLOBAL g, my_bool b = false); 62 my_bool CalcLen(UDF_ARGS* args, my_bool obj, unsigned long& reslen, 63 unsigned long& memlen, my_bool mod = false); 64 my_bool JsonInit(UDF_INIT* initid, UDF_ARGS* args, char* message, my_bool mbn, 65 unsigned long reslen, unsigned long memlen, 66 unsigned long more = 0); 67 my_bool CheckMemory(PGLOBAL g, UDF_INIT* initid, UDF_ARGS* args, uint n, 68 my_bool m, my_bool obj = false, my_bool mod = false); 69 PSZ MakePSZ(PGLOBAL g, UDF_ARGS* args, int i); 70 int IsJson(UDF_ARGS* args, uint i, bool b = false); 71 char *GetJsonFile(PGLOBAL g, char* fn); 72 73 /*********************************************************************************/ 74 /* The JSON UDF functions. */ 75 /*********************************************************************************/ 76 extern "C" { 77 DllExport my_bool jsonvalue_init(UDF_INIT*, UDF_ARGS*, char*); 78 DllExport char *jsonvalue(UDF_EXEC_ARGS); 79 DllExport void jsonvalue_deinit(UDF_INIT*); 80 81 DllExport my_bool json_make_array_init(UDF_INIT*, UDF_ARGS*, char*); 82 DllExport char *json_make_array(UDF_EXEC_ARGS); 83 DllExport void json_make_array_deinit(UDF_INIT*); 84 85 DllExport my_bool json_array_add_values_init(UDF_INIT*, UDF_ARGS*, char*); 86 DllExport char *json_array_add_values(UDF_EXEC_ARGS); 87 DllExport void json_array_add_values_deinit(UDF_INIT*); 88 89 DllExport my_bool json_array_add_init(UDF_INIT*, UDF_ARGS*, char*); 90 DllExport char *json_array_add(UDF_EXEC_ARGS); 91 DllExport void json_array_add_deinit(UDF_INIT*); 92 93 DllExport my_bool json_array_delete_init(UDF_INIT*, UDF_ARGS*, char*); 94 DllExport char *json_array_delete(UDF_EXEC_ARGS); 95 DllExport void json_array_delete_deinit(UDF_INIT*); 96 97 DllExport my_bool jsonsum_int_init(UDF_INIT*, UDF_ARGS*, char*); 98 DllExport long long jsonsum_int(UDF_INIT*, UDF_ARGS*, char*, char*); 99 DllExport void jsonsum_int_deinit(UDF_INIT*); 100 101 DllExport my_bool jsonsum_real_init(UDF_INIT*, UDF_ARGS*, char*); 102 DllExport double jsonsum_real(UDF_INIT*, UDF_ARGS*, char*, char*); 103 DllExport void jsonsum_real_deinit(UDF_INIT*); 104 105 DllExport my_bool jsonavg_real_init(UDF_INIT*, UDF_ARGS*, char*); 106 DllExport double jsonavg_real(UDF_INIT*, UDF_ARGS*, char*, char*); 107 DllExport void jsonavg_real_deinit(UDF_INIT*); 108 109 DllExport my_bool json_make_object_init(UDF_INIT*, UDF_ARGS*, char*); 110 DllExport char *json_make_object(UDF_EXEC_ARGS); 111 DllExport void json_make_object_deinit(UDF_INIT*); 112 113 DllExport my_bool json_object_nonull_init(UDF_INIT*, UDF_ARGS*, char*); 114 DllExport char *json_object_nonull(UDF_EXEC_ARGS); 115 DllExport void json_object_nonull_deinit(UDF_INIT*); 116 117 DllExport my_bool json_object_key_init(UDF_INIT*, UDF_ARGS*, char*); 118 DllExport char *json_object_key(UDF_EXEC_ARGS); 119 DllExport void json_object_key_deinit(UDF_INIT*); 120 121 DllExport my_bool json_object_add_init(UDF_INIT*, UDF_ARGS*, char*); 122 DllExport char *json_object_add(UDF_EXEC_ARGS); 123 DllExport void json_object_add_deinit(UDF_INIT*); 124 125 DllExport my_bool json_object_delete_init(UDF_INIT*, UDF_ARGS*, char*); 126 DllExport char *json_object_delete(UDF_EXEC_ARGS); 127 DllExport void json_object_delete_deinit(UDF_INIT*); 128 129 DllExport my_bool json_object_list_init(UDF_INIT*, UDF_ARGS*, char*); 130 DllExport char *json_object_list(UDF_EXEC_ARGS); 131 DllExport void json_object_list_deinit(UDF_INIT*); 132 133 DllExport my_bool json_object_values_init(UDF_INIT*, UDF_ARGS*, char*); 134 DllExport char *json_object_values(UDF_EXEC_ARGS); 135 DllExport void json_object_values_deinit(UDF_INIT*); 136 137 DllExport my_bool jsonset_grp_size_init(UDF_INIT*, UDF_ARGS*, char*); 138 DllExport long long jsonset_grp_size(UDF_INIT*, UDF_ARGS*, char*, char*); 139 140 DllExport my_bool jsonget_grp_size_init(UDF_INIT*, UDF_ARGS*, char*); 141 DllExport long long jsonget_grp_size(UDF_INIT*, UDF_ARGS*, char*, char*); 142 143 DllExport my_bool json_array_grp_init(UDF_INIT*, UDF_ARGS*, char*); 144 DllExport void json_array_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *); 145 DllExport char *json_array_grp(UDF_EXEC_ARGS); 146 DllExport void json_array_grp_clear(UDF_INIT *, char *, char *); 147 DllExport void json_array_grp_deinit(UDF_INIT*); 148 149 DllExport my_bool json_object_grp_init(UDF_INIT*, UDF_ARGS*, char*); 150 DllExport void json_object_grp_add(UDF_INIT *, UDF_ARGS *, char *, char *); 151 DllExport char *json_object_grp(UDF_EXEC_ARGS); 152 DllExport void json_object_grp_clear(UDF_INIT *, char *, char *); 153 DllExport void json_object_grp_deinit(UDF_INIT*); 154 155 DllExport my_bool json_item_merge_init(UDF_INIT*, UDF_ARGS*, char*); 156 DllExport char *json_item_merge(UDF_EXEC_ARGS); 157 DllExport void json_item_merge_deinit(UDF_INIT*); 158 159 DllExport my_bool json_get_item_init(UDF_INIT*, UDF_ARGS*, char*); 160 DllExport char *json_get_item(UDF_EXEC_ARGS); 161 DllExport void json_get_item_deinit(UDF_INIT*); 162 163 DllExport my_bool jsonget_string_init(UDF_INIT*, UDF_ARGS*, char*); 164 DllExport char *jsonget_string(UDF_EXEC_ARGS); 165 DllExport void jsonget_string_deinit(UDF_INIT*); 166 167 DllExport my_bool jsonget_int_init(UDF_INIT*, UDF_ARGS*, char*); 168 DllExport long long jsonget_int(UDF_INIT*, UDF_ARGS*, char*, char*); 169 DllExport void jsonget_int_deinit(UDF_INIT*); 170 171 DllExport my_bool jsonget_real_init(UDF_INIT*, UDF_ARGS*, char*); 172 DllExport double jsonget_real(UDF_INIT*, UDF_ARGS*, char*, char*); 173 DllExport void jsonget_real_deinit(UDF_INIT*); 174 175 DllExport my_bool jsoncontains_init(UDF_INIT*, UDF_ARGS*, char*); 176 DllExport long long jsoncontains(UDF_INIT*, UDF_ARGS*, char*, char*); 177 DllExport void jsoncontains_deinit(UDF_INIT*); 178 179 DllExport my_bool jsonlocate_init(UDF_INIT*, UDF_ARGS*, char*); 180 DllExport char *jsonlocate(UDF_EXEC_ARGS); 181 DllExport void jsonlocate_deinit(UDF_INIT*); 182 183 DllExport my_bool json_locate_all_init(UDF_INIT*, UDF_ARGS*, char*); 184 DllExport char *json_locate_all(UDF_EXEC_ARGS); 185 DllExport void json_locate_all_deinit(UDF_INIT*); 186 187 DllExport my_bool jsoncontains_path_init(UDF_INIT*, UDF_ARGS*, char*); 188 DllExport long long jsoncontains_path(UDF_INIT*, UDF_ARGS*, char*, char*); 189 DllExport void jsoncontains_path_deinit(UDF_INIT*); 190 191 DllExport my_bool json_set_item_init(UDF_INIT*, UDF_ARGS*, char*); 192 DllExport char *json_set_item(UDF_EXEC_ARGS); 193 DllExport void json_set_item_deinit(UDF_INIT*); 194 195 DllExport my_bool json_insert_item_init(UDF_INIT*, UDF_ARGS*, char*); 196 DllExport char *json_insert_item(UDF_EXEC_ARGS); 197 DllExport void json_insert_item_deinit(UDF_INIT*); 198 199 DllExport my_bool json_update_item_init(UDF_INIT*, UDF_ARGS*, char*); 200 DllExport char *json_update_item(UDF_EXEC_ARGS); 201 DllExport void json_update_item_deinit(UDF_INIT*); 202 203 DllExport my_bool json_file_init(UDF_INIT*, UDF_ARGS*, char*); 204 DllExport char *json_file(UDF_EXEC_ARGS); 205 DllExport void json_file_deinit(UDF_INIT*); 206 207 DllExport my_bool jfile_make_init(UDF_INIT*, UDF_ARGS*, char*); 208 DllExport char *jfile_make(UDF_EXEC_ARGS); 209 DllExport void jfile_make_deinit(UDF_INIT*); 210 211 DllExport my_bool jbin_array_init(UDF_INIT*, UDF_ARGS*, char*); 212 DllExport char *jbin_array(UDF_EXEC_ARGS); 213 DllExport void jbin_array_deinit(UDF_INIT*); 214 215 DllExport my_bool jbin_array_add_values_init(UDF_INIT*, UDF_ARGS*, char*); 216 DllExport char *jbin_array_add_values(UDF_EXEC_ARGS); 217 DllExport void jbin_array_add_values_deinit(UDF_INIT*); 218 219 DllExport my_bool jbin_array_add_init(UDF_INIT*, UDF_ARGS*, char*); 220 DllExport char *jbin_array_add(UDF_EXEC_ARGS); 221 DllExport void jbin_array_add_deinit(UDF_INIT*); 222 223 DllExport my_bool jbin_array_delete_init(UDF_INIT*, UDF_ARGS*, char*); 224 DllExport char *jbin_array_delete(UDF_EXEC_ARGS); 225 DllExport void jbin_array_delete_deinit(UDF_INIT*); 226 227 DllExport my_bool jbin_object_init(UDF_INIT*, UDF_ARGS*, char*); 228 DllExport char *jbin_object(UDF_EXEC_ARGS); 229 DllExport void jbin_object_deinit(UDF_INIT*); 230 231 DllExport my_bool jbin_object_nonull_init(UDF_INIT*, UDF_ARGS*, char*); 232 DllExport char *jbin_object_nonull(UDF_EXEC_ARGS); 233 DllExport void jbin_object_nonull_deinit(UDF_INIT*); 234 235 DllExport my_bool jbin_object_key_init(UDF_INIT*, UDF_ARGS*, char*); 236 DllExport char *jbin_object_key(UDF_EXEC_ARGS); 237 DllExport void jbin_object_key_deinit(UDF_INIT*); 238 239 DllExport my_bool jbin_object_add_init(UDF_INIT*, UDF_ARGS*, char*); 240 DllExport char *jbin_object_add(UDF_EXEC_ARGS); 241 DllExport void jbin_object_add_deinit(UDF_INIT*); 242 243 DllExport my_bool jbin_object_delete_init(UDF_INIT*, UDF_ARGS*, char*); 244 DllExport char *jbin_object_delete(UDF_EXEC_ARGS); 245 DllExport void jbin_object_delete_deinit(UDF_INIT*); 246 247 DllExport my_bool jbin_object_list_init(UDF_INIT*, UDF_ARGS*, char*); 248 DllExport char *jbin_object_list(UDF_EXEC_ARGS); 249 DllExport void jbin_object_list_deinit(UDF_INIT*); 250 251 DllExport my_bool jbin_get_item_init(UDF_INIT*, UDF_ARGS*, char*); 252 DllExport char *jbin_get_item(UDF_EXEC_ARGS); 253 DllExport void jbin_get_item_deinit(UDF_INIT*); 254 255 DllExport my_bool jbin_item_merge_init(UDF_INIT*, UDF_ARGS*, char*); 256 DllExport char *jbin_item_merge(UDF_EXEC_ARGS); 257 DllExport void jbin_item_merge_deinit(UDF_INIT*); 258 259 DllExport my_bool jbin_set_item_init(UDF_INIT*, UDF_ARGS*, char*); 260 DllExport char *jbin_set_item(UDF_EXEC_ARGS); 261 DllExport void jbin_set_item_deinit(UDF_INIT*); 262 263 DllExport my_bool jbin_insert_item_init(UDF_INIT*, UDF_ARGS*, char*); 264 DllExport char *jbin_insert_item(UDF_EXEC_ARGS); 265 DllExport void jbin_insert_item_deinit(UDF_INIT*); 266 267 DllExport my_bool jbin_update_item_init(UDF_INIT*, UDF_ARGS*, char*); 268 DllExport char *jbin_update_item(UDF_EXEC_ARGS); 269 DllExport void jbin_update_item_deinit(UDF_INIT*); 270 271 DllExport my_bool jbin_file_init(UDF_INIT*, UDF_ARGS*, char*); 272 DllExport char *jbin_file(UDF_EXEC_ARGS); 273 DllExport void jbin_file_deinit(UDF_INIT*); 274 275 DllExport my_bool json_serialize_init(UDF_INIT*, UDF_ARGS*, char*); 276 DllExport char *json_serialize(UDF_EXEC_ARGS); 277 DllExport void json_serialize_deinit(UDF_INIT*); 278 279 DllExport my_bool jfile_convert_init(UDF_INIT*, UDF_ARGS*, char*); 280 DllExport char* jfile_convert(UDF_EXEC_ARGS); 281 DllExport void jfile_convert_deinit(UDF_INIT*); 282 283 DllExport my_bool jfile_bjson_init(UDF_INIT*, UDF_ARGS*, char*); 284 DllExport char* jfile_bjson(UDF_EXEC_ARGS); 285 DllExport void jfile_bjson_deinit(UDF_INIT*); 286 287 DllExport my_bool envar_init(UDF_INIT*, UDF_ARGS*, char*); 288 DllExport char *envar(UDF_EXEC_ARGS); 289 290 #if defined(DEVELOPMENT) 291 DllExport my_bool uvar_init(UDF_INIT*, UDF_ARGS*, char*); 292 DllExport char *uvar(UDF_EXEC_ARGS); 293 #endif // DEVELOPMENT 294 295 DllExport my_bool countin_init(UDF_INIT*, UDF_ARGS*, char*); 296 DllExport long long countin(UDF_INIT*, UDF_ARGS*, char*, char*); 297 } // extern "C" 298 299 300 /*********************************************************************************/ 301 /* Structure JPN. Used to make the locate path. */ 302 /*********************************************************************************/ 303 typedef struct _jpn { 304 int Type; 305 PCSZ Key; 306 int N; 307 } JPN, *PJPN; 308 309 /*********************************************************************************/ 310 /* Class JSNX: JSON access method. */ 311 /*********************************************************************************/ 312 class JSNX : public BLOCK { 313 public: 314 // Constructors 315 JSNX(PGLOBAL g, PJSON row, int type, int len = 64, int prec = 0, my_bool wr = false); 316 317 // Implementation GetPrecision(void)318 int GetPrecision(void) {return Prec;} GetValue(void)319 PVAL GetValue(void) {return Value;} 320 321 // Methods 322 my_bool SetJpath(PGLOBAL g, char *path, my_bool jb = false); 323 my_bool ParseJpath(PGLOBAL g); 324 void ReadValue(PGLOBAL g); 325 PJVAL GetRowValue(PGLOBAL g, PJSON row, int i, my_bool b = true); 326 PJVAL GetJson(PGLOBAL g); 327 my_bool CheckPath(PGLOBAL g); 328 my_bool WriteValue(PGLOBAL g, PJVAL jvalp); 329 char *Locate(PGLOBAL g, PJSON jsp, PJVAL jvp, int k = 1); 330 char *LocateAll(PGLOBAL g, PJSON jsp, PJVAL jvp, int mx = 10); 331 332 protected: 333 my_bool SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm); 334 PVAL GetColumnValue(PGLOBAL g, PJSON row, int i); 335 PVAL ExpandArray(PGLOBAL g, PJAR arp, int n); 336 PVAL GetCalcValue(PGLOBAL g, PJAR bap, int n); 337 PVAL CalculateArray(PGLOBAL g, PJAR arp, int n); 338 PJVAL MakeJson(PGLOBAL g, PJSON jsp, int i); 339 void SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val); 340 PJSON GetRow(PGLOBAL g); 341 my_bool CompareValues(PJVAL v1, PJVAL v2); 342 my_bool LocateArray(PGLOBAL g, PJAR jarp); 343 my_bool LocateObject(PGLOBAL g, PJOB jobp); 344 my_bool LocateValue(PGLOBAL g, PJVAL jvp); 345 my_bool LocateArrayAll(PGLOBAL g, PJAR jarp); 346 my_bool LocateObjectAll(PGLOBAL g, PJOB jobp); 347 my_bool LocateValueAll(PGLOBAL g, PJVAL jvp); 348 my_bool CompareTree(PGLOBAL g, PJSON jp1, PJSON jp2); 349 my_bool AddPath(void); 350 351 // Default constructor not to be used JSNX(void)352 JSNX(void) {} 353 354 // Members 355 PJSON Row; 356 PJVAL Jvalp; 357 PJPN Jpnp; 358 JOUTSTR *Jp; 359 JNODE *Nodes; // The intermediate objects 360 PVAL Value; 361 //PVAL MulVal; // To value used by multiple column 362 char *Jpath; // The json path 363 int Buf_Type; 364 int Long; 365 int Prec; 366 int Nod; // The number of intermediate objects 367 int Xnod; // Index of multiple values 368 int K; // Kth item to locate 369 int I; // Index of JPN 370 int Imax; // Max number of JPN's 371 int B; // Index base 372 my_bool Xpd; // True for expandable column 373 my_bool Parsed; // True when parsed 374 my_bool Found; // Item found by locate 375 my_bool Wr; // Write mode 376 my_bool Jb; // Must return json item 377 }; // end of class JSNX 378 379 /*********************************************************************************/ 380 /* Class JUP: used by jfile_convert to make a json file pretty = 0. */ 381 /*********************************************************************************/ 382 class JUP : public BLOCK { 383 public: 384 // Constructor 385 JUP(PGLOBAL g); 386 387 // Implementation AddBuff(char c)388 void AddBuff(char c) { 389 if (k < recl) 390 buff[k++] = c; 391 else 392 throw "Record size is too small"; 393 } // end of AddBuff 394 395 // Methods 396 char *UnprettyJsonFile(PGLOBAL g, char* fn, char* outfn, int lrecl); 397 bool unPretty(PGLOBAL g, int lrecl); 398 void CopyObject(PGLOBAL g); 399 void CopyArray(PGLOBAL g); 400 void CopyValue(PGLOBAL g); 401 void CopyString(PGLOBAL g); 402 void CopyNumeric(PGLOBAL g); 403 404 // Members 405 FILE *fs; 406 char *s; 407 char *buff; 408 size_t len; 409 uint i; 410 int k, recl; 411 }; // end of class JUP 412