1 #pragma once 2 #ifndef JQL_H 3 #define JQL_H 4 5 /************************************************************************************************** 6 * EJDB2 7 * 8 * MIT License 9 * 10 * Copyright (c) 2012-2021 Softmotions Ltd <info@softmotions.com> 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a copy 13 * of this software and associated documentation files (the "Software"), to deal 14 * in the Software without restriction, including without limitation the rights 15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 * copies of the Software, and to permit persons to whom the Software is 17 * furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be included in all 20 * copies or substantial portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 * SOFTWARE. 29 *************************************************************************************************/ 30 31 /** @file 32 * 33 * @brief EJDB query construction API. 34 * 35 * EJDB query syntax inpired by ideas behind XPath and Unix shell pipes. 36 * 37 * 38 */ 39 40 #include "jbl.h" 41 #include <ejdb2/iowow/iwlog.h> 42 43 IW_EXTERN_C_START 44 45 struct _JQL; 46 typedef struct _JQL*JQL; 47 48 typedef enum { 49 _JQL_ERROR_START = (IW_ERROR_START + 15000UL + 2000), 50 JQL_ERROR_QUERY_PARSE, /**< Query parsing error (JQL_ERROR_QUERY_PARSE) */ 51 JQL_ERROR_INVALID_PLACEHOLDER, /**< Invalid placeholder position (JQL_ERROR_INVALID_PLACEHOLDER) */ 52 JQL_ERROR_UNSET_PLACEHOLDER, /**< Found unset placeholder (JQL_ERROR_UNSET_PLACEHOLDER) */ 53 JQL_ERROR_REGEXP_INVALID, /**< Invalid regular expression (JQL_ERROR_REGEXP_INVALID) */ 54 JQL_ERROR_REGEXP_CHARSET, 55 /**< Invalid regular expression: expected ']' at end of character set 56 (JQL_ERROR_REGEXP_CHARSET) */ 57 JQL_ERROR_REGEXP_SUBEXP, 58 /**< Invalid regular expression: expected ')' at end of subexpression 59 (JQL_ERROR_REGEXP_SUBEXP) */ 60 JQL_ERROR_REGEXP_SUBMATCH, 61 /**< Invalid regular expression: expected '}' at end of submatch 62 (JQL_ERROR_REGEXP_SUBMATCH) */ 63 JQL_ERROR_REGEXP_ENGINE, 64 /**< Illegal instruction in compiled regular expression (please report this 65 bug) (JQL_ERROR_REGEXP_ENGINE) */ 66 JQL_ERROR_SKIP_ALREADY_SET, /**< Skip clause already specified (JQL_ERROR_SKIP_ALREADY_SET) */ 67 JQL_ERROR_LIMIT_ALREADY_SET, /**< Limit clause already specified (JQL_ERROR_SKIP_ALREADY_SET) */ 68 JQL_ERROR_ORDERBY_MAX_LIMIT, 69 /**< Reached max number of asc/desc order clauses: 64 70 (JQL_ERROR_ORDERBY_MAX_LIMIT) */ 71 JQL_ERROR_NO_COLLECTION, /**< No collection specified in query (JQL_ERROR_NO_COLLECTION) */ 72 JQL_ERROR_INVALID_PLACEHOLDER_VALUE_TYPE, 73 /**< Invalid type of placeholder value 74 (JQL_ERROR_INVALID_PLACEHOLDER_VALUE_TYPE) */ 75 _JQL_ERROR_END, 76 _JQL_ERROR_UNMATCHED, 77 } jql_ecode_t; 78 79 typedef uint8_t jql_create_mode_t; 80 81 /// Do not destroy query object in `jql_create()` on query parsing error, 82 /// convenient for parsing error reporting using `jql_error()` 83 #define JQL_KEEP_QUERY_ON_PARSE_ERROR ((jql_create_mode_t) 0x01U) 84 85 /// Do not print query parsing errors to `stderr` 86 #define JQL_SILENT_ON_PARSE_ERROR ((jql_create_mode_t) 0x02U) 87 88 /** 89 * @brief Create query object from specified text query. 90 * @param qptr Pointer to resulting query object 91 * @param coll Optional collection name used to execute query 92 * @param query Query text 93 */ 94 IW_EXPORT WUR iwrc jql_create(JQL *qptr, const char *coll, const char *query); 95 96 IW_EXPORT WUR iwrc jql_create2(JQL *qptr, const char *coll, const char *query, jql_create_mode_t mode); 97 98 IW_EXPORT const char *jql_collection(JQL q); 99 100 /** 101 * @brief Bind JSON node data to query placeholder. 102 * @warning Value JSON data is not copied and used as is. 103 * Caller is responsible to maintain `val` availability during execution of query. 104 * @see jql_set_json2() 105 */ 106 IW_EXPORT WUR iwrc jql_set_json(JQL q, const char *placeholder, int index, JBL_NODE val); 107 108 IW_EXPORT WUR iwrc jql_set_json2( 109 JQL q, const char *placeholder, int index, JBL_NODE val, 110 void (*freefn)(void*, void*), void *op); 111 112 IW_EXPORT WUR iwrc jql_set_json_jbl(JQL q, const char *placeholder, int index, JBL jbl); 113 114 IW_EXPORT WUR iwrc jql_set_i64(JQL q, const char *placeholder, int index, int64_t val); 115 116 IW_EXPORT WUR iwrc jql_set_f64(JQL q, const char *placeholder, int index, double val); 117 118 /** 119 * @brief Bind string data to query placeholder. 120 * @warning Value string data is not copied and used as is. 121 * Caller is responsible to maintain `val` availability during execution of query. 122 * @see jql_set_str2() 123 */ 124 IW_EXPORT WUR iwrc jql_set_str(JQL q, const char *placeholder, int index, const char *val); 125 126 IW_EXPORT WUR iwrc jql_set_str2( 127 JQL q, const char *placeholder, int index, const char *val, 128 void (*freefn)(void*, void*), void *op); 129 130 IW_EXPORT WUR iwrc jql_set_bool(JQL q, const char *placeholder, int index, bool val); 131 132 133 /** 134 * @brief Bind regexp data string to query placeholder. 135 * @warning Value string data is not copied and used as is. 136 * Caller is responsible to maintain `val` availability during execution of query. 137 * @see jql_set_regexp2() 138 */ 139 IW_EXPORT WUR iwrc jql_set_regexp(JQL q, const char *placeholder, int index, const char *expr); 140 141 IW_EXPORT WUR iwrc jql_set_regexp2( 142 JQL q, const char *placeholder, int index, const char *expr, 143 void (*freefn)(void*, void*), void *op); 144 145 IW_EXPORT WUR iwrc jql_set_null(JQL q, const char *placeholder, int index); 146 147 IW_EXPORT WUR iwrc jql_matched(JQL q, JBL jbl, bool *out); 148 149 IW_EXPORT const char *jql_first_anchor(JQL q); 150 151 IW_EXPORT const char *jql_error(JQL q); 152 153 IW_EXPORT bool jql_has_apply(JQL q); 154 155 IW_EXPORT bool jql_has_apply_upsert(JQL q); 156 157 IW_EXPORT bool jql_has_apply_delete(JQL q); 158 159 IW_EXPORT bool jql_has_projection(JQL q); 160 161 IW_EXPORT bool jql_has_orderby(JQL q); 162 163 IW_EXPORT bool jql_has_aggregate_count(JQL q); 164 165 IW_EXPORT iwrc jql_get_skip(JQL q, int64_t *out); 166 167 IW_EXPORT iwrc jql_get_limit(JQL q, int64_t *out); 168 169 IW_EXPORT WUR iwrc jql_apply(JQL q, JBL_NODE root, IWPOOL *pool); 170 171 IW_EXPORT WUR iwrc jql_project(JQL q, JBL_NODE root, IWPOOL *pool, void *exec_ctx); 172 173 IW_EXPORT WUR iwrc jql_apply_and_project(JQL q, JBL jbl, JBL_NODE *out, void *exec_ctx, IWPOOL *pool); 174 175 IW_EXPORT void jql_reset(JQL q, bool reset_match_cache, bool reset_placeholders); 176 177 IW_EXPORT void jql_destroy(JQL *qptr); 178 179 IW_EXPORT size_t jql_estimate_allocated_size(JQL q); 180 181 IW_EXPORT WUR iwrc jql_init(void); 182 183 IW_EXTERN_C_END 184 #endif 185