Qore Programming Language 1.19.1
Loading...
Searching...
No Matches
qore_dbi_private.h
1/* -*- mode: c++; indent-tabs-mode: nil -*- */
2/*
3 qore_dbi_private.h
4
5 Qore Programming Language
6
7 Copyright (C) 2003 - 2023 Qore Technologies, s.r.o.
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 and/or sell copies of the Software, and to permit persons to whom the
14 Software is furnished to do so, subject to the following conditions:
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26
27 Note that the Qore library is released under a choice of three open-source
28 licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29 information.
30*/
31
32#ifndef _QORE_QORE_DBI_PRIVATE_H
33#define _QORE_QORE_DBI_PRIVATE_H
34
35#include <map>
36
37// internal DBI definitions
38typedef std::map<int, void*> dbi_method_list_t;
39hashdecl DbiOptInfo {
40 const char* desc = nullptr;
41 const QoreTypeInfo *typeInfo = nullptr;
42
43 DLLLOCAL DbiOptInfo() {
44 }
45
46 DLLLOCAL DbiOptInfo(const char* d, const QoreTypeInfo* t) : desc(d), typeInfo(t) {
47 }
48};
49typedef std::map<const char*, DbiOptInfo, ltcstrcase> dbi_opt_map_t;
50
51hashdecl dbi_driver_stmt {
52 q_dbi_stmt_prepare_t prepare = nullptr;
53 q_dbi_stmt_prepare_raw_t prepare_raw = nullptr;
54 q_dbi_stmt_bind_t bind = nullptr,
55 bind_placeholders = nullptr,
56 bind_values = nullptr;
57 q_dbi_stmt_exec_t exec = nullptr,
58 exec_describe = nullptr;
59 q_dbi_stmt_fetch_row_t fetch_row = nullptr;
60 q_dbi_stmt_fetch_rows_t fetch_rows = nullptr;
61 q_dbi_stmt_fetch_columns_t fetch_columns = nullptr;
62 q_dbi_stmt_fetch_row_t describe = nullptr;
63 q_dbi_stmt_next_t next = nullptr;
64 q_dbi_stmt_define_t define = nullptr;
65 q_dbi_stmt_close_t close = nullptr,
66 free = nullptr;
67 q_dbi_stmt_affected_rows_t affected_rows = nullptr;
68 q_dbi_stmt_get_output_t get_output = nullptr;
69 q_dbi_stmt_get_output_rows_t get_output_rows = nullptr;
70
71 DLLLOCAL dbi_driver_stmt() {
72 }
73};
74
75hashdecl dbi_driver_opt {
76 q_dbi_option_set_t set = nullptr;
77 q_dbi_option_get_t get = nullptr;
78
79 DLLLOCAL dbi_driver_opt() {
80 }
81};
82
83hashdecl DBIDriverFunctions {
84 q_dbi_open_t open = nullptr;
85 q_dbi_close_t close = nullptr;
86 q_dbi_select_t select = nullptr;
87 q_dbi_select_rows_t selectRows = nullptr;
88 q_dbi_select_row_t selectRow = nullptr;
89 q_dbi_exec_t execSQL = nullptr;
90 q_dbi_execraw_t execRawSQL = nullptr;
91 q_dbi_describe_t describe = nullptr;
92 q_dbi_commit_t commit = nullptr;
93 q_dbi_rollback_t rollback = nullptr;
94 q_dbi_begin_transaction_t begin_transaction = nullptr; // for DBI drivers that require explicit transaction starts
95 q_dbi_get_server_version_t get_server_version = nullptr;
96 q_dbi_get_client_version_t get_client_version = nullptr;
97 q_dbi_get_driver_real_name_t get_driver_real_name = nullptr;
98
99 dbi_driver_stmt stmt;
100 dbi_driver_opt opt;
101
102 DLLLOCAL DBIDriverFunctions() {
103 }
104};
105
106// helper class that will edit argument lists and convert number values to floats if the driver does not support the "number" type (QoreNumberNode)
107class DbiArgHelper {
108protected:
109 const QoreListNode* orig;
110 QoreListNode* nl;
111 ExceptionSink* xsink;
112
113public:
114 DLLLOCAL DbiArgHelper(const QoreListNode* ol, bool numeric, ExceptionSink* xs);
115
116 DLLLOCAL ~DbiArgHelper() {
117 if (nl)
118 nl->deref(xsink);
119 }
120
121 DLLLOCAL const QoreListNode* get() const {
122 return nl ? nl : orig;
123 }
124
125 DLLLOCAL const QoreListNode* operator*() const {
126 return nl ? nl : orig;
127 }
128};
129
130hashdecl OptInputHelper {
131 ExceptionSink* xsink;
132 QoreValue val;
133 bool tmp;
134
135 DLLLOCAL OptInputHelper(ExceptionSink* xs, const qore_dbi_private& driver, const char* opt, bool set = false, const QoreValue v = QoreValue());
136
137 DLLLOCAL ~OptInputHelper() {
138 if (tmp)
139 val.discard(xsink);
140 }
141
142 DLLLOCAL operator bool() const {
143 assert(xsink);
144 return !*xsink;
145 }
146};
147
148hashdecl qore_dbi_private {
149 const char* name;
150 int caps;
151 DBIDriverFunctions f;
152 dbi_opt_map_t omap;
153
154 DLLLOCAL qore_dbi_private(const char* nme, const qore_dbi_mlist_private& methods, int cps);
155
156 DLLLOCAL bool hasStatementAPI() const {
157 return caps & DBI_CAP_HAS_STATEMENT;
158 }
159
160 DLLLOCAL int init(Datasource* ds, ExceptionSink* xsink) const {
161 assert(xsink);
162 int rc = f.open(ds, xsink);
163 assert((!rc && !*xsink) || (rc && *xsink));
164 // set option if init was successful
165 if (!rc && f.opt.set) {
167 while (hi.next()) {
168 f.opt.set(ds, hi.getKey(), hi.get(), xsink);
169 }
170 }
171 return rc;
172 }
173
174 DLLLOCAL int close(Datasource* ds) const {
175 return f.close(ds);
176 }
177
178 DLLLOCAL QoreValue select(Datasource* ds, const QoreString* sql, const QoreListNode* args, ExceptionSink* xsink) const {
179 DbiArgHelper dargs(args, (caps & DBI_CAP_HAS_NUMBER_SUPPORT), xsink);
180 return f.select(ds, sql, *dargs, xsink);
181 }
182
183 DLLLOCAL QoreValue selectRows(Datasource* ds, const QoreString* sql, const QoreListNode* args, ExceptionSink* xsink) const {
184 DbiArgHelper dargs(args, (caps & DBI_CAP_HAS_NUMBER_SUPPORT), xsink);
185 return f.selectRows(ds, sql, *dargs, xsink);
186 }
187
188 DLLLOCAL QoreHashNode* selectRow(Datasource* ds, const QoreString* sql, const QoreListNode* args, ExceptionSink* xsink) const {
189 DbiArgHelper dargs(args, (caps & DBI_CAP_HAS_NUMBER_SUPPORT), xsink);
190
191 if (f.selectRow) {
192 return f.selectRow(ds, sql, *dargs, xsink);
193 }
194
195 ValueHolder res(f.selectRows(ds, sql, *dargs, xsink), xsink);
196 if (!res) {
197 return nullptr;
198 }
199
200 if (res->getType() != NT_HASH) {
201 assert(res->getType() == NT_LIST);
202 assert(res->getInternalNode()->reference_count() == 1);
203 QoreListNode* l = res->get<QoreListNode>();
204 assert(l->size() <= 1);
205 QoreValue n = l->shift();
206 assert(n.isNothing() || n.getType() == NT_HASH);
207 return n.get<QoreHashNode>();
208 }
209
210 return res.release().get<QoreHashNode>();
211 }
212
213 DLLLOCAL QoreValue execSQL(Datasource* ds, const QoreString* sql, const QoreListNode* args, ExceptionSink* xsink) const {
214 DbiArgHelper dargs(args, (caps & DBI_CAP_HAS_NUMBER_SUPPORT), xsink);
215 return f.execSQL(ds, sql, *dargs, xsink);
216 }
217
218 DLLLOCAL QoreValue execRawSQL(Datasource* ds, const QoreString* sql, ExceptionSink* xsink) const {
219 if (!f.execRawSQL) {
220 xsink->raiseException("DBI-EXEC-RAW-SQL-ERROR", "this driver does not implement the Datasource::execRawSQL() method");
221 return QoreValue();
222 }
223 return f.execRawSQL(ds, sql, xsink);
224 }
225
226 DLLLOCAL QoreHashNode* describe(Datasource* ds, const QoreString* sql, const QoreListNode* args, ExceptionSink* xsink) {
227 if (!f.describe) {
228 xsink->raiseException("DBI-DESCRIBE-ERROR", "this driver does not implement the Datasource::describe() method");
229 return nullptr;
230 }
231 DbiArgHelper dargs(args, (caps & DBI_CAP_HAS_NUMBER_SUPPORT), xsink);
232 return f.describe(ds, sql, *dargs, xsink);
233 }
234
235 DLLLOCAL int commit(Datasource* ds, ExceptionSink* xsink) const {
236 return f.commit(ds, xsink);
237 }
238
239 DLLLOCAL int rollback(Datasource* ds, ExceptionSink* xsink) const {
240 return f.rollback(ds, xsink);
241 }
242
243 DLLLOCAL int beginTransaction(Datasource* ds, ExceptionSink* xsink) const {
244 if (f.begin_transaction)
245 return f.begin_transaction(ds, xsink);
246 return 0; // 0 = OK
247 }
248
249 DLLLOCAL int autoCommit(Datasource* ds, ExceptionSink* xsink) const {
250 // if the driver does not require explicit "begin" statements to
251 // start a transaction, then we have to explicitly call "commit" here
252 if (!f.begin_transaction)
253 return f.commit(ds, xsink);
254
255 return 0; // 0 = OK
256 }
257
258 DLLLOCAL QoreValue getServerVersion(Datasource* ds, ExceptionSink* xsink) const {
259 if (f.get_server_version)
260 return f.get_server_version(ds, xsink);
261 return QoreValue();
262 }
263
264 DLLLOCAL QoreValue getClientVersion(const Datasource* ds, ExceptionSink* xsink) const {
265 if (f.get_client_version)
266 return f.get_client_version(ds, xsink);
267 return QoreValue();
268 }
269
270 DLLLOCAL QoreStringNode* getDriverRealName(Datasource* ds, ExceptionSink* xsink) const {
271 if (f.get_driver_real_name) {
272 return f.get_driver_real_name(ds, xsink);
273 }
274 return new QoreStringNode(ds->getDriverName());
275 }
276
277 DLLLOCAL int getCaps() const {
278 return caps;
279 }
280
281 DLLLOCAL QoreListNode* getCapList() const;
282
283 DLLLOCAL bool hasExecDefine() const {
284 return (bool)f.stmt.exec_describe;
285 }
286
287 DLLLOCAL int stmt_prepare(SQLStatement* stmt, const QoreString& str, const QoreListNode* args, ExceptionSink* xsink) const {
288 DbiArgHelper dargs(args, (caps & DBI_CAP_HAS_NUMBER_SUPPORT), xsink);
289 return f.stmt.prepare(stmt, str, *dargs, xsink);
290 }
291
292 DLLLOCAL int stmt_prepare_raw(SQLStatement* stmt, const QoreString& str, ExceptionSink* xsink) const {
293 return f.stmt.prepare_raw(stmt, str, xsink);
294 }
295
296 DLLLOCAL int stmt_bind(SQLStatement* stmt, const QoreListNode& l, ExceptionSink* xsink) const {
297 return f.stmt.bind(stmt, l, xsink);
298 }
299
300 DLLLOCAL int stmt_bind_placeholders(SQLStatement* stmt, const QoreListNode& l, ExceptionSink* xsink) const {
301 if (!f.stmt.bind_placeholders) {
302 xsink->raiseException("SQLSTATEMENT-BIND-PLACEHOLDERS-ERROR", "the '%s' driver does not require placeholder buffer specifications so the SQLStatement::bindPlaceholders() method is not supported", name);
303 return -1;
304 }
305
306 return f.stmt.bind_placeholders(stmt, l, xsink);
307 }
308
309 DLLLOCAL int stmt_bind_values(SQLStatement* stmt, const QoreListNode& l, ExceptionSink* xsink) const {
310 return f.stmt.bind_values(stmt, l, xsink);
311 }
312
313 DLLLOCAL int stmt_define(SQLStatement* stmt, ExceptionSink* xsink) const {
314 return f.stmt.define(stmt, xsink);
315 }
316
317 DLLLOCAL int stmt_exec_describe(SQLStatement* stmt, ExceptionSink* xsink) const {
318 assert(f.stmt.exec_describe);
319 return f.stmt.exec_describe(stmt, xsink);
320 }
321
322 DLLLOCAL int stmt_exec(SQLStatement* stmt, ExceptionSink* xsink) const {
323 return f.stmt.exec(stmt, xsink);
324 }
325
326 DLLLOCAL int stmt_affected_rows(SQLStatement* stmt, ExceptionSink* xsink) const {
327 return f.stmt.affected_rows(stmt, xsink);
328 }
329
330 DLLLOCAL QoreHashNode* stmt_get_output(SQLStatement* stmt, ExceptionSink* xsink) const {
331 return f.stmt.get_output(stmt, xsink);
332 }
333
334 DLLLOCAL QoreHashNode* stmt_get_output_rows(SQLStatement* stmt, ExceptionSink* xsink) const {
335 return f.stmt.get_output_rows(stmt, xsink);
336 }
337
338 DLLLOCAL QoreHashNode* stmt_fetch_row(SQLStatement* stmt, ExceptionSink* xsink) const {
339 return f.stmt.fetch_row(stmt, xsink);
340 }
341
342 DLLLOCAL QoreListNode* stmt_fetch_rows(SQLStatement* stmt, int rows, ExceptionSink* xsink) const {
343 return f.stmt.fetch_rows(stmt, rows, xsink);
344 }
345
346 DLLLOCAL QoreHashNode* stmt_fetch_columns(SQLStatement* stmt, int rows, ExceptionSink* xsink) const {
347 return f.stmt.fetch_columns(stmt, rows, xsink);
348 }
349
350 DLLLOCAL QoreHashNode* stmt_describe(SQLStatement* stmt, ExceptionSink* xsink) const {
351 if (!f.stmt.describe) {
352 xsink->raiseException("DBI-DESCRIBE-ERROR", "this driver does not implement the SQLStatement::describe() method");
353 return nullptr;
354 }
355 return f.stmt.describe(stmt, xsink);
356 }
357
358 DLLLOCAL bool stmt_next(SQLStatement* stmt, ExceptionSink* xsink) const {
359 return f.stmt.next(stmt, xsink);
360 }
361
362 DLLLOCAL int stmt_close(SQLStatement* stmt, ExceptionSink* xsink) const {
363 return f.stmt.close(stmt, xsink);
364 }
365
366 DLLLOCAL int stmt_free(SQLStatement* stmt, ExceptionSink* xsink) const {
367 return f.stmt.free ? f.stmt.free(stmt, xsink) : 0;
368 }
369
370 DLLLOCAL int opt_set(Datasource* ds, const char* opt, const QoreValue val, ExceptionSink* xsink) {
371 OptInputHelper oh(xsink, *this, opt, true, val);
372 if (!oh)
373 return -1;
374
375 return f.opt.set(ds, opt, oh.val, xsink);
376 }
377
378 DLLLOCAL QoreValue opt_get(const Datasource* ds, const char* opt, ExceptionSink* xsink) {
379 OptInputHelper oh(xsink, *this, opt);
380 if (!oh)
381 return QoreValue();
382
383 return f.opt.get(ds, opt);
384 }
385
386 DLLLOCAL QoreHashNode* getOptionHash(const Datasource* ds) const {
387 QoreHashNode* rv = new QoreHashNode(autoTypeInfo);
388
389 for (dbi_opt_map_t::const_iterator i = omap.begin(), e = omap.end(); i != e; ++i) {
390 QoreHashNode* h = new QoreHashNode(autoTypeInfo);
391 h->setKeyValue("desc", new QoreStringNode(i->second.desc), 0);
392 h->setKeyValue("type", new QoreStringNode(QoreTypeInfo::getName(i->second.typeInfo)), 0);
393 h->setKeyValue("value", f.opt.get(ds, i->first), 0);
394
395 rv->setKeyValue(i->first, h, 0);
396 }
397 return rv;
398 }
399
400 DLLLOCAL QoreHashNode* getOptionHash() const {
401 QoreHashNode* rv = new QoreHashNode(autoTypeInfo);
402
403 for (dbi_opt_map_t::const_iterator i = omap.begin(), e = omap.end(); i != e; ++i) {
404 QoreHashNode* h = new QoreHashNode(autoTypeInfo);
405 h->setKeyValue("desc", new QoreStringNode(i->second.desc), 0);
406 h->setKeyValue("type", new QoreStringNode(QoreTypeInfo::getName(i->second.typeInfo)), 0);
407
408 rv->setKeyValue(i->first, h, 0);
409 }
410 return rv;
411 }
412
413 DLLLOCAL static qore_dbi_private* get(const DBIDriver& d) {
414 return d.priv;
415 }
416};
417
418#endif
int(* q_dbi_rollback_t)(Datasource *ds, ExceptionSink *xsink)
signature for the DBI "rollback" method - must be defined in each DBI driver
Definition: DBI.h:203
QoreValue(* q_dbi_get_client_version_t)(const Datasource *ds, ExceptionSink *xsink)
signature for the "get_client_version" method
Definition: DBI.h:227
#define DBI_CAP_HAS_NUMBER_SUPPORT
supports arbitrary-precision numeric support for binding and retrieving values; if this is not true t...
Definition: DBI.h:51
#define DBI_CAP_HAS_STATEMENT
supports the SQLStatement class (set automatically by the Qore library)
Definition: DBI.h:49
QoreValue(* q_dbi_exec_t)(Datasource *ds, const QoreString *str, const QoreListNode *args, ExceptionSink *xsink)
signature for the DBI "execSQL" method - must be defined in each DBI driver
Definition: DBI.h:178
int(* q_dbi_stmt_exec_t)(SQLStatement *stmt, ExceptionSink *xsink)
execute statement
Definition: DBI.h:255
QoreHashNode *(* q_dbi_select_row_t)(Datasource *ds, const QoreString *str, const QoreListNode *args, ExceptionSink *xsink)
signature for the DBI "selectRow" method - must be defined in each DBI driver
Definition: DBI.h:168
QoreStringNode *(* q_dbi_get_driver_real_name_t)(Datasource *ds, ExceptionSink *xsink)
signature for the "get_driver_real_name" method
Definition: DBI.h:235
int(* q_dbi_stmt_prepare_raw_t)(SQLStatement *stmt, const QoreString &str, ExceptionSink *xsink)
prepare statement with no bind parsing
Definition: DBI.h:245
QoreValue(* q_dbi_select_t)(Datasource *ds, const QoreString *str, const QoreListNode *args, ExceptionSink *xsink)
signature for the DBI "select" method - must be defined in each DBI driver
Definition: DBI.h:147
QoreValue(* q_dbi_select_rows_t)(Datasource *ds, const QoreString *str, const QoreListNode *args, ExceptionSink *xsink)
signature for the DBI "selectRows" method - must be defined in each DBI driver
Definition: DBI.h:157
QoreHashNode *(* q_dbi_stmt_get_output_t)(SQLStatement *stmt, ExceptionSink *xsink)
get output values, any row sets are returned as a hash of lists
Definition: DBI.h:265
int(* q_dbi_begin_transaction_t)(Datasource *ds, ExceptionSink *xsink)
signature for the DBI "begin_transaction" method, should only be defined for drivers needing this to ...
Definition: DBI.h:211
int(* q_dbi_stmt_bind_t)(SQLStatement *stmt, const QoreListNode &l, ExceptionSink *xsink)
bind input values and optionally describe output parameters
Definition: DBI.h:250
QoreHashNode *(* q_dbi_describe_t)(Datasource *ds, const QoreString *str, const QoreListNode *args, ExceptionSink *xsink)
signature for the DBI "describe" method
Definition: DBI.h:290
int(* q_dbi_commit_t)(Datasource *ds, ExceptionSink *xsink)
signature for the DBI "commit" method - must be defined in each DBI driver
Definition: DBI.h:195
int(* q_dbi_open_t)(Datasource *ds, ExceptionSink *xsink)
signature for the DBI "open" method - must be defined in each DBI driver
Definition: DBI.h:130
int(* q_dbi_close_t)(Datasource *ds)
signature for the DBI "close" method - must be defined in each DBI driver
Definition: DBI.h:137
QoreValue(* q_dbi_get_server_version_t)(Datasource *ds, ExceptionSink *xsink)
signature for the "get_server_version" method
Definition: DBI.h:219
int(* q_dbi_stmt_affected_rows_t)(SQLStatement *stmt, ExceptionSink *xsink)
get number of affected rows
Definition: DBI.h:260
QoreHashNode *(* q_dbi_stmt_get_output_rows_t)(SQLStatement *stmt, ExceptionSink *xsink)
get output values, any row sets are returned as a list of hashes
Definition: DBI.h:270
QoreValue(* q_dbi_execraw_t)(Datasource *ds, const QoreString *str, ExceptionSink *xsink)
signature for the DBI "execRawSQL" method - must be defined in each DBI driver
Definition: DBI.h:187
int(* q_dbi_stmt_prepare_t)(SQLStatement *stmt, const QoreString &str, const QoreListNode *args, ExceptionSink *xsink)
prepare statement and process placeholder specifications and bind parameters
Definition: DBI.h:240
DLLEXPORT void deref(ExceptionSink *xsink)
decrements the reference count and calls derefImpl() if there_can_be_only_one is false,...
constant iterator class for QoreHashNode, to be only created on the stack
Definition: QoreHashNode.h:590
this class provides the internal link to the database driver for Qore's DBI layer
Definition: DBI.h:367
the base class for accessing databases in Qore through a Qore DBI driver
Definition: Datasource.h:55
DLLEXPORT const QoreHashNode * getConnectOptions() const
returns the valid options for this driver with descriptions and current values for the current dataso...
DLLEXPORT const char * getDriverName() const
returns the name of the current Qore DBI driver
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:50
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
This is the hash or associative list container type in Qore, dynamically allocated only,...
Definition: QoreHashNode.h:50
DLLEXPORT int setKeyValue(const char *key, QoreValue value, ExceptionSink *xsink)
sets the value of "key" to "value"
This is the list container type in Qore, dynamically allocated only, reference counted.
Definition: QoreListNode.h:52
DLLEXPORT QoreValue shift()
returns the first element of the list, all other entries are moved down to fill up the first position...
DLLEXPORT size_t size() const
returns the number of elements in the list
DLLLOCAL detail::QoreValueCastHelper< T >::Result get()
returns the value as the given type
Definition: QoreValue.h:214
DLLEXPORT qore_type_t getType() const
returns the type of value contained
DLLEXPORT bool isNothing() const
returns true if the object contains NOTHING
Qore's string type supported by the QoreEncoding class.
Definition: QoreString.h:93
Qore's string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
This is the public class for DBI drivers supporting Qore's new prepared statement API.
Definition: SQLStatement.h:38
holds an object and dereferences it in the destructor
Definition: QoreValue.h:487
const qore_type_t NT_LIST
type value for QoreListNode
Definition: node_types.h:50
const qore_type_t NT_HASH
type value for QoreHashNode
Definition: node_types.h:51
The main value class in Qore, designed to be passed by value.
Definition: QoreValue.h:276
DLLEXPORT void discard(ExceptionSink *xsink)
dereferences any contained AbstractQoreNode pointer and sets to 0; does not modify other values