Loading...
Searching...
No Matches
abrain.c File Reference

abrain.c - 25 Aug 2024 - aotto1968 More...

#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include "sqlite3.h"
#include "msgque_mq.h"
#include "debug_mq.h"
+ Include dependency graph for abrain.c:

Go to the source code of this file.

Data Structures

struct  BrainCtxS
 the local context of the server tool More...
 

Macros

#define META_FILE_NAME   "abrain.c"
 
#define BrainT   ((typeof(MqContextST)) BrainTT)
 
#define BRAINCTX   ((struct BrainCtxS*const)mqctx)
 
#define MQCTX   ((MQ_CTX*const)brain)
 
#define META_CONTEXT_S   mqctx
 
#define SETUP_brain   struct BrainCtxS*const brain = BRAINCTX
 
#define SETUP_db   sqlite3*const db = brain->db
 
#define SETUP_W(sh)
 
#define SETUP_C(sh)
 
#define DbErrorCheck(f)
 
#define CHECK_ARGS(s)
 
#define check_sqlite(E)
 
#define check_NULL(E)
 
#define DB_PREPARE_MAX   100
 
#define READ_C(n)
 
#define IdxGet(...)
 
#define IdxFinalize(...)
 
#define HdlGet(...)
 
#define ctxCleanup(...)
 
#define case1(t, f, c)
 
#define GetFromDBnat(...)
 
#define GetFromDBary(...)
 

Functions

static void BrainHelp (const char *base)
 display help using -h or --help command-line option
 
static enum MkErrorE IdxGet_RT (MK_RT const mkrt, MQ_CTX const mqctx, MK_I32 *pidx)
 
static enum MkErrorE IdxFinalize_RT (MK_RT const mkrt, MQ_CTX const mqctx, MK_I32 idx)
 
static enum MkErrorE HdlGet_RT (MK_RT const mkrt, MQ_CTX const mqctx, sqlite3_stmt **phdl, MK_STRN *pInType, MK_STRN *pInEnd, MK_STRN *pOutType, MK_STRN *pOutEnd)
 
static enum MkErrorE ctxCleanup_RT (MK_RT const mkrt, MQ_CTX const mqctx)
 
static enum MkTypeE GetTypeE (MK_STRB t)
 
static MK_STRB GetTypeS (enum MkTypeE const ntype)
 
static enum MkTypeE GetTypeD (sqlite3_stmt *hdl, MK_I32 idx)
 
static enum MkErrorE GetFromDBnat_RT (MK_RT const mkrt, MQ_CTX const mqctx, enum MkTypeE ntype, sqlite3_stmt *hdl, MK_I32 idx)
 
static enum MkErrorE GetFromDBary_RT (MK_RT const mkrt, MQ_CTX const mqctx, enum MkTypeE ntype, sqlite3_stmt *hdl, MK_I32 idx)
 
static enum MkErrorE STEP (MQ_SERVICE_CALL_ARGS)
 
static enum MkErrorE EXEC (MQ_SERVICE_CALL_ARGS)
 
static enum MkErrorE PREP (MQ_SERVICE_CALL_ARGS)
 
static enum MkErrorE FINA (MQ_SERVICE_CALL_ARGS)
 
static enum MkErrorE OPEN (MQ_SERVICE_CALL_ARGS)
 
static enum MkErrorE CLOS (MQ_SERVICE_CALL_ARGS)
 
static enum MkErrorE BrainCleanup (MQ_SERVICE_CALL_ARGS)
 
static enum MkErrorE BrainSetup (MQ_SERVICE_CALL_ARGS)
 
static enum MkErrorE BrainFactory (MQ_CALLBACK_FACTORY_CTOR_ARGS)
 
int main (const int argc, MK_STRN argv[])
 main entry-point for the tool
 

Variables

static MK_TYP BrainTT = NULL
 link to the MqErrorS object
 

Detailed Description

abrain.c - 25 Aug 2024 - aotto1968

Version
c3b28928437a81158df1f3cafe23fbded7b34813
Date
Sun Aug 25 22:59:57 2024 +0200
Author
aotto1968 aotto.nosp@m.1968.nosp@m.@t-on.nosp@m.line.nosp@m..de

Definition in file abrain.c.

Macro Definition Documentation

◆ BRAINCTX

#define BRAINCTX   ((struct BrainCtxS*const)mqctx)

Definition at line 32 of file abrain.c.

◆ BrainT

#define BrainT   ((typeof(MqContextST)) BrainTT)

Definition at line 31 of file abrain.c.

◆ case1

#define case1 ( t,
f,
c )
Value:
case t##T: { \
t dat; \
MkErrorCheck(MkBufferGet ## c(buf,&dat)); \
DbErrorCheck(f(hdl,idx,dat)); \
break; \
}

Definition at line 246 of file abrain.c.

246#define case1(t,f,c) \
247 case t##T: { \
248 t dat; \
249 MkErrorCheck(MkBufferGet ## c(buf,&dat)); \
250 DbErrorCheck(f(hdl,idx,dat)); \
251 break; \
252 }

◆ CHECK_ARGS

#define CHECK_ARGS ( s)
Value:
if (MqReadGetNumItems(mqctx)) { \
return MkErrorSetV_4M (mqctx, __func__, SQLITE_ERROR, "usage: %s (%s)\n", __func__, s); \
}
#define MkErrorSetV_4M(m,...)
MQ_EXTERN MK_NUM MqReadGetNumItems(MQ_CTX const ctx) MK_ATTR_HDL

Definition at line 50 of file abrain.c.

50#define CHECK_ARGS(s) \
51 if (MqReadGetNumItems(mqctx)) { \
52 return MkErrorSetV_4M (mqctx, __func__, SQLITE_ERROR, "usage: %s (%s)\n", __func__, s); \
53 }

◆ check_NULL

#define check_NULL ( E)
Value:
if (unlikely((E) == NULL))
#define unlikely(x)

Definition at line 56 of file abrain.c.

56#define check_NULL(E) \
57 if (unlikely((E) == NULL))

◆ check_sqlite

#define check_sqlite ( E)
Value:
if (unlikely((E) != SQLITE_OK))

Definition at line 54 of file abrain.c.

54#define check_sqlite(E) \
55 if (unlikely((E) != SQLITE_OK))

◆ ctxCleanup

#define ctxCleanup ( ...)
Value:
static enum MkErrorE ctxCleanup_RT(MK_RT const mkrt, MQ_CTX const mqctx)
Definition abrain.c:169
#define MK_RT_CALL

Definition at line 186 of file abrain.c.

◆ DB_PREPARE_MAX

#define DB_PREPARE_MAX   100

Definition at line 59 of file abrain.c.

◆ DbErrorCheck

#define DbErrorCheck ( f)
Value:
if (unlikely((f) != SQLITE_OK)) { \
MkErrorSetC_4M (mqctx, sqlite3_errmsg(brain->db), __func__, sqlite3_extended_errcode(brain->db)); \
goto error; \
}

Definition at line 45 of file abrain.c.

45#define DbErrorCheck(f) \
46 if (unlikely((f) != SQLITE_OK)) { \
47 MkErrorSetC_4M (mqctx, sqlite3_errmsg(brain->db), __func__, sqlite3_extended_errcode(brain->db)); \
48 goto error; \
49 }

◆ GetFromDBary

#define GetFromDBary ( ...)
Value:
static enum MkErrorE GetFromDBary_RT(MK_RT const mkrt, MQ_CTX const mqctx, enum MkTypeE ntype, sqlite3_stmt *hdl, MK_I32 idx)
Definition abrain.c:279

Definition at line 303 of file abrain.c.

◆ GetFromDBnat

#define GetFromDBnat ( ...)
Value:
static enum MkErrorE GetFromDBnat_RT(MK_RT const mkrt, MQ_CTX const mqctx, enum MkTypeE ntype, sqlite3_stmt *hdl, MK_I32 idx)
Definition abrain.c:254

Definition at line 277 of file abrain.c.

◆ HdlGet

#define HdlGet ( ...)
Value:
HdlGet_RT(MK_RT_CALL __VA_ARGS__)
static enum MkErrorE HdlGet_RT(MK_RT const mkrt, MQ_CTX const mqctx, sqlite3_stmt **phdl, MK_STRN *pInType, MK_STRN *pInEnd, MK_STRN *pOutType, MK_STRN *pOutEnd)
Definition abrain.c:142

Definition at line 167 of file abrain.c.

◆ IdxFinalize

#define IdxFinalize ( ...)
Value:
static enum MkErrorE IdxFinalize_RT(MK_RT const mkrt, MQ_CTX const mqctx, MK_I32 idx)
Definition abrain.c:125

Definition at line 140 of file abrain.c.

◆ IdxGet

#define IdxGet ( ...)
Value:
IdxGet_RT(MK_RT_CALL __VA_ARGS__)
static enum MkErrorE IdxGet_RT(MK_RT const mkrt, MQ_CTX const mqctx, MK_I32 *pidx)
Definition abrain.c:112

Definition at line 123 of file abrain.c.

◆ META_CONTEXT_S

#define META_CONTEXT_S   mqctx

Definition at line 34 of file abrain.c.

◆ META_FILE_NAME

#define META_FILE_NAME   "abrain.c"

Definition at line 15 of file abrain.c.

◆ MQCTX

#define MQCTX   ((MQ_CTX*const)brain)

Definition at line 33 of file abrain.c.

◆ READ_C

#define READ_C ( n)
Value:
MK_STRN n; MkErrorCheck(MqReadSTR(mqctx,&n))
const MK_STRB * MK_STRN
#define MqReadSTR(...)

Definition at line 104 of file abrain.c.

◆ SETUP_brain

#define SETUP_brain   struct BrainCtxS*const brain = BRAINCTX

Definition at line 35 of file abrain.c.

◆ SETUP_C

#define SETUP_C ( sh)
Value:
MK_STRN key; MK_SIZE klen; \
register sqlite3_stmt *hdl= brain->sh
#define SETUP_brain
Definition abrain.c:35
long MK_SIZE

Definition at line 41 of file abrain.c.

41#define SETUP_C(sh) \
42 SETUP_brain; \
43 MK_STRN key; MK_SIZE klen; \
44 register sqlite3_stmt *hdl= brain->sh

◆ SETUP_db

#define SETUP_db   sqlite3*const db = brain->db

Definition at line 36 of file abrain.c.

◆ SETUP_W

#define SETUP_W ( sh)
Value:
MK_I64 key; \
register sqlite3_stmt *hdl= brain->sh
signed long long MK_I64

Definition at line 37 of file abrain.c.

37#define SETUP_W(sh) \
38 SETUP_brain; \
39 MK_I64 key; \
40 register sqlite3_stmt *hdl= brain->sh

Function Documentation

◆ BrainCleanup()

static enum MkErrorE BrainCleanup ( MQ_SERVICE_CALL_ARGS )
static

Definition at line 568 of file abrain.c.

569{
571 MkBufferDelete(brain->buf);
572 MkErrorCheck(ctxCleanup(mqctx));
573
574 return MK_OK;
575error:
576 return MkErrorStack_1X(mqctx);
577}
#define ctxCleanup(...)
Definition abrain.c:186
#define MkBufferDelete(x)
#define MkErrorStack_1X(...)
MK_OK
+ Here is the caller graph for this function:

◆ BrainFactory()

static enum MkErrorE BrainFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS )
static

Definition at line 599 of file abrain.c.

600{
601 MQ_CTX const mqctx = *contextP = MqContextCreate(BrainTT,tmpl);
602
603 mqctx->setup.isServer = true;
606
607 return MK_OK;
608}
static enum MkErrorE BrainCleanup(MQ_SERVICE_CALL_ARGS)
Definition abrain.c:568
static MK_TYP BrainTT
link to the MqErrorS object
Definition abrain.c:30
static enum MkErrorE BrainSetup(MQ_SERVICE_CALL_ARGS)
Definition abrain.c:580
#define MqContextCreate(...)
MqTokenF fCall
struct MqSetupS setup
struct MqCallbackS ServerCleanup
struct MqCallbackS ServerSetup
bool isServer
+ Here is the caller graph for this function:

◆ BrainHelp()

static void BrainHelp ( const char * base)
static

display help using -h or --help command-line option

Parameters
basethe executable usually: basename(argv[0])

Definition at line 84 of file abrain.c.

85{
86 fprintf (stderr, "usage: %s [OPTION]... [ARGUMENT]...\n", base);
87 fputs ("\n", stderr);
88 fputs (" This tool is the database server of NHI1.\n", stderr);
89 fputs (" main: https://theBrain.nhi1.de\n", stderr);
90 fputs (" tool: https://thebrain.nhi1.de/theBrain.htm\n", stderr);
91 fputs ("\n", stderr);
92 fprintf (stderr, " %s [ARGUMENT]... syntax:\n", base);
93 fprintf (stderr, " aclient [OPTION]... %c %s [OPTION]... [ARGUMENT]\n", MK_ALFA, base);
94 fputs ("\n", stderr);
95 fputs (MqHelp (NULL), stderr);
96 fputs ("\n", stderr);
97 fprintf (stderr," %s [OPTION]:\n", base);
98 fputs (" -h, --help print this help\n", stderr);
99 fputs ("\n", stderr);
100
101 exit(EXIT_SUCCESS);
102}
#define MK_ALFA
MQ_EXTERN MK_STR MqHelp(MK_STRN tool)
+ Here is the caller graph for this function:

◆ BrainSetup()

static enum MkErrorE BrainSetup ( MQ_SERVICE_CALL_ARGS )
static

Definition at line 580 of file abrain.c.

581{
583 brain->prepare_start=0;
584 brain->buf = MkBufferCreate(MkBuffer1024STT,10);
585 MkErrorCheck (MqServiceCreate (mqctx, "OPEN", OPEN, NULL, NULL, NULL));
586
587 return MK_OK;
588error:
589 return MkErrorStack_1X(mqctx);
590}
static enum MkErrorE OPEN(MQ_SERVICE_CALL_ARGS)
Definition abrain.c:529
#define MkBuffer1024STT
#define MkBufferCreate(...)
#define MqServiceCreate(...)
+ Here is the caller graph for this function:

◆ CLOS()

static enum MkErrorE CLOS ( MQ_SERVICE_CALL_ARGS )
static

Definition at line 520 of file abrain.c.

520 {
521 MkErrorCheck (ctxCleanup(mqctx));
522 MkErrorCheck (MqServiceDelete (mqctx, "-ALL"));
523 MkErrorCheck (MqServiceCreate (mqctx, "OPEN", OPEN, NULL, NULL, NULL));
524
525error:
526 return MqSendRETURN(mqctx);
527}
#define MqSendRETURN(...)
#define MqServiceDelete(...)
+ Here is the caller graph for this function:

◆ ctxCleanup_RT()

static enum MkErrorE ctxCleanup_RT ( MK_RT const mkrt,
MQ_CTX const mqctx )
static

Definition at line 169 of file abrain.c.

169 {
171 MkSysFree (brain->storage);
172 if (brain->db != NULL) {
173 for (MK_I32 idx=0; idx<brain->prepare_start; idx++) {
174 MkErrorCheck (IdxFinalize (mqctx, idx));
175 }
176 brain->prepare_start=0;
177 DbErrorCheck(sqlite3_close(brain->db))
178 brain->db=NULL;
179 }
180 return MK_OK;
181error:
182 brain->db = NULL;
183 return MkErrorStack_1X(mqctx);
184}
#define DbErrorCheck(f)
Definition abrain.c:45
#define IdxFinalize(...)
Definition abrain.c:140
signed int MK_I32
#define MkSysFree(pointer)

◆ EXEC()

static enum MkErrorE EXEC ( MQ_SERVICE_CALL_ARGS )
static

Definition at line 418 of file abrain.c.

418 {
420 MK_STRN sql;
421 MkErrorCheck(MqReadSTR(mqctx,&sql));
422 DbErrorCheck(sqlite3_exec(brain->db,sql, NULL, NULL, NULL));
423
424error:
425 return MqSendRETURN(mqctx);
426}
+ Here is the caller graph for this function:

◆ FINA()

static enum MkErrorE FINA ( MQ_SERVICE_CALL_ARGS )
static

Definition at line 510 of file abrain.c.

510 {
511 MK_I32 idx;
512 MkErrorCheck(IdxGet(mqctx, &idx));
513 MkErrorCheck(IdxFinalize(mqctx, idx));
514error:
515 return MqSendRETURN(mqctx);
516}
#define IdxGet(...)
Definition abrain.c:123
+ Here is the caller graph for this function:

◆ GetFromDBary_RT()

static enum MkErrorE GetFromDBary_RT ( MK_RT const mkrt,
MQ_CTX const mqctx,
enum MkTypeE ntype,
sqlite3_stmt * hdl,
MK_I32 idx )
inlinestatic

Definition at line 279 of file abrain.c.

285 {
286 switch (ntype) {
287 case MK_BINT:
288 MqSendBIN_E(mqctx,MkBinaryCreate(sqlite3_column_bytes(hdl,idx),sqlite3_column_blob(hdl,idx)));
289 break;
290 case MK_STRT:
291 MqSendSTR_E(mqctx,(MK_STRN)sqlite3_column_text(hdl,idx));
292 break;
293 default:
294 MkBufferCastTo_E( MkBufferSetSTR(BRAINCTX->buf, (MK_STRN)sqlite3_column_text(hdl, idx)), ntype);
295 MqSendBUF_E(mqctx, BRAINCTX->buf);
296 break;
297 }
298 return MK_OK;
299error:
300 return MkErrorStack_1X(mqctx);
301}
#define BRAINCTX
Definition abrain.c:32
#define MkBufferCastTo_E(...)
#define MkBufferSetSTR(...)
MkBinaryR MkBinaryCreate(MK_SIZE size, MK_BINN data)
MK_BINT
MK_STRT
#define MqSendBUF_E(...)
#define MqSendSTR_E(...)
#define MqSendBIN_E(...)

◆ GetFromDBnat_RT()

static enum MkErrorE GetFromDBnat_RT ( MK_RT const mkrt,
MQ_CTX const mqctx,
enum MkTypeE ntype,
sqlite3_stmt * hdl,
MK_I32 idx )
inlinestatic

Definition at line 254 of file abrain.c.

260 {
261 switch (ntype) {
262 case MK_STRT: return MqSendSTR(mqctx,(MK_STRN)sqlite3_column_text(hdl,idx));
263 case MK_I32T: return MqSendI32(mqctx,(MK_I32)sqlite3_column_int(hdl,idx));
264 case MK_I16T: return MqSendI16(mqctx,(MK_I16)sqlite3_column_int(hdl,idx));
265 case MK_I8T: return MqSendI8(mqctx,(MK_I8)sqlite3_column_int(hdl,idx));
266 case MK_BOLT: return MqSendBOL(mqctx,(MK_BOL)sqlite3_column_int(hdl,idx));
267 case MK_I64T: return MqSendI64(mqctx,(MK_I64)sqlite3_column_int64(hdl,idx));
268 case MK_DBLT: return MqSendDBL(mqctx,(MK_DBL)sqlite3_column_double(hdl,idx));
269 case MK_FLTT: return MqSendFLT(mqctx,(MK_FLT)sqlite3_column_double(hdl,idx));
270 case MK_BINT: return MqSendBIN(mqctx,MkBinaryCreate(sqlite3_column_bytes(hdl,idx),sqlite3_column_blob(hdl,idx)));
271 case MK_LSTT:
272 return MkErrorSetV_4M (mqctx, __func__, SQLITE_ERROR, "invalid protocoll item '%c'", GetTypeS(ntype));
273 }
274 return MK_BINT;
275}
static MK_STRB GetTypeS(enum MkTypeE const ntype)
Definition abrain.c:210
MK_I8T
MK_I64T
MK_FLTT
MK_I16T
MK_BOLT
MK_DBLT
MK_I32T
MK_LSTT
float MK_FLT
signed char MK_I8
unsigned char MK_BOL
signed short int MK_I16
double MK_DBL
#define MqSendBIN(...)
#define MqSendI8(...)
#define MqSendBOL(...)
#define MqSendI64(...)
#define MqSendI32(...)
#define MqSendI16(...)
#define MqSendSTR(...)
#define MqSendFLT(...)
#define MqSendDBL(...)

◆ GetTypeD()

static enum MkTypeE GetTypeD ( sqlite3_stmt * hdl,
MK_I32 idx )
inlinestatic

Definition at line 226 of file abrain.c.

226 {
227 switch (sqlite3_column_type(hdl,idx)) {
228 case SQLITE_INTEGER:
229 switch (sqlite3_column_bytes(hdl,idx)) {
230 case 1: return MK_I8T;
231 case 2: return MK_I16T;
232 case 3:
233 case 4: return MK_I32T;
234 case 6:
235 case 8: return MK_I64T;
236 }
237 break;
238 case SQLITE_FLOAT: return MK_DBLT;
239 case SQLITE_BLOB: return MK_BINT;
240 case SQLITE_TEXT: return MK_STRT;
241 case SQLITE_NULL: return MK_BINT;
242 }
243 return MK_BINT;
244}
+ Here is the caller graph for this function:

◆ GetTypeE()

static enum MkTypeE GetTypeE ( MK_STRB t)
inlinestatic

Definition at line 194 of file abrain.c.

194 {
195 switch (t) {
196 case 'C': return MK_STRT;
197 case 'I': return MK_I32T;
198 case 'D': return MK_DBLT;
199 case 'W': return MK_I64T;
200 case 'B': return MK_BINT;
201 case 'Y': return MK_I8T;
202 case 'O': return MK_BOLT;
203 case 'S': return MK_I16T;
204 case 'F': return MK_FLTT;
205 case 'L': return MK_LSTT;
206 }
207 return MK_STRT;
208}
+ Here is the caller graph for this function:

◆ GetTypeS()

static MK_STRB GetTypeS ( enum MkTypeE const ntype)
inlinestatic

Definition at line 210 of file abrain.c.

210 {
211 switch (ntype) {
212 case MK_STRT: return 'C';
213 case MK_I32T: return 'I';
214 case MK_DBLT: return 'D';
215 case MK_I64T: return 'W';
216 case MK_BINT: return 'B';
217 case MK_I8T: return 'Y';
218 case MK_BOLT: return 'O';
219 case MK_I16T: return 'S';
220 case MK_FLTT: return 'F';
221 case MK_LSTT: return 'L';
222 }
223 return '*';
224}
+ Here is the caller graph for this function:

◆ HdlGet_RT()

static enum MkErrorE HdlGet_RT ( MK_RT const mkrt,
MQ_CTX const mqctx,
sqlite3_stmt ** phdl,
MK_STRN * pInType,
MK_STRN * pInEnd,
MK_STRN * pOutType,
MK_STRN * pOutEnd )
inlinestatic

Definition at line 142 of file abrain.c.

150 {
152 MK_I32 idx;
153 MkErrorCheck (IdxGet (mqctx, &idx));
154 check_NULL(*phdl = brain->prepStmt[idx]) {
155 MkErrorSetV_4M (mqctx, __func__, SQLITE_ERROR, "the prepare-index '%i' was NOT defined", idx);
156 goto error;
157 }
158 *pInType = brain->inType[idx];
159 *pInEnd = brain->inEnd[idx];
160 *pOutType = brain->outType[idx];
161 *pOutEnd = brain->outEnd[idx];
162 return MK_OK;
163error:
164 return MkErrorStack_1X(mqctx);
165}
#define check_NULL(E)
Definition abrain.c:56

◆ IdxFinalize_RT()

static enum MkErrorE IdxFinalize_RT ( MK_RT const mkrt,
MQ_CTX const mqctx,
MK_I32 idx )
inlinestatic

Definition at line 125 of file abrain.c.

125 {
127 if (brain->prepStmt[idx] != NULL) {
128 DbErrorCheck(sqlite3_finalize(brain->prepStmt[idx]));
129 brain->prepStmt[idx] = NULL;
130 MkSysFree(brain->inType[idx]);
131 brain->inEnd[idx] = NULL;
132 MkSysFree(brain->outType[idx]);
133 brain->outEnd[idx] = NULL;
134 }
135 return MK_OK;
136error:
137 return MkErrorStack_1X(mqctx);
138}

◆ IdxGet_RT()

static enum MkErrorE IdxGet_RT ( MK_RT const mkrt,
MQ_CTX const mqctx,
MK_I32 * pidx )
static

Definition at line 112 of file abrain.c.

112 {
113 MkErrorCheck (MqReadI32 (mqctx, pidx));
114 if (*pidx < 0 || *pidx > DB_PREPARE_MAX-1) {
115 MkErrorSetV_4M (mqctx, __func__, SQLITE_ERROR, "prepare index out of range: 0 <= idx <= %i", DB_PREPARE_MAX-1);
116 goto error;
117 }
118 return MK_OK;
119error:
120 return MkErrorStack_1X(mqctx);
121}
#define DB_PREPARE_MAX
Definition abrain.c:59
#define MqReadI32(...)

◆ main()

int main ( const int argc,
MK_STRN argv[] )

main entry-point for the tool

Parameters
argcthe number of command-line arguments
argvthe command-line arguments as an array of strings
Returns
the exit number

Definition at line 616 of file abrain.c.

620{
621 MqSetup();
622 MqRtSetup_NULL;
623
624 // define the new type
625 BrainTT = MkTypeDup2(MqContextSTT, "BrainTT");
626 BrainTT->objsize = sizeof(struct BrainCtxS);
627 BrainT->fHelp = BrainHelp;
628
629 // parse the command-line
630 MK_BFL args = MkBufferListCreateVC (argc, argv);
631 MQ_CTX mqctx = NULL;
632
633 // call Factory
634 MQ_FCT fct = MqFactoryAdd_2(BrainFactory, "abrain");
635 MqFactoryNew_E (fct, NULL, &mqctx);
636
637 // create the ServerCtxS
638 MqLinkCreate_E (mqctx, args);
639
640 // start event-loop and wait forever
642
643 // finish and exit
644error:
645 MkBufferListDelete(args);
646 MqExit_1 (mqctx);
647}
static enum MkErrorE BrainFactory(MQ_CALLBACK_FACTORY_CTOR_ARGS)
Definition abrain.c:599
static void BrainHelp(const char *base)
display help using -h or --help command-line option
Definition abrain.c:84
#define BrainT
Definition abrain.c:31
#define MkBufferListCreateVC(...)
#define MkBufferListDelete(x)
MK_TIMEOUT_DEFAULT
#define MkTypeDup2(...)
#define MqContextSTT
#define MqExit_1(ctx)
#define MqProcessEvent_E(...)
#define MqFactoryNew_E(...)
#define MqFactoryAdd_2(fct, ident)
MQ_WAIT_FOREVER
MQ_EXTERN void MqSetup(void)
the local context of the server tool
Definition abrain.c:62
MQ_CTXR mqctx
the LibMqMsgque context object
Definition abrain.c:63
size_t objsize

◆ OPEN()

static enum MkErrorE OPEN ( MQ_SERVICE_CALL_ARGS )
static

Definition at line 529 of file abrain.c.

529 {
531
532 // open storage
533 {
534 MK_STRN dbstorage;
535 MkErrorCheck(MqReadSTR(mqctx,&dbstorage));
536
537 if (dbstorage == NULL) {
538 return MkErrorSetC_4M (mqctx, "storage-file is empty or invalid", __func__, SQLITE_ERROR);
539 }
540
541 MkDLogV(mqctx,5,"try to open database '%s'\n", dbstorage);
542
543 // open the database
544 DbErrorCheck (sqlite3_open(dbstorage, &brain->db));
545 }
546
547 // add/remove services
548 MkErrorCheck (MqServiceDelete (mqctx, "OPEN"));
549
550 MkErrorCheck (MqServiceCreate (mqctx, "CLOS", CLOS, NULL, NULL, NULL));
551 MkErrorCheck (MqServiceCreate (mqctx, "EXEC", EXEC, NULL, NULL, NULL));
552 MkErrorCheck (MqServiceCreate (mqctx, "PREP", PREP, NULL, NULL, NULL));
553 MkErrorCheck (MqServiceCreate (mqctx, "FINA", FINA, NULL, NULL, NULL));
554 MkErrorCheck (MqServiceCreate (mqctx, "STEP", STEP, NULL, NULL, NULL));
555
556 MqSendSTART(mqctx);
557error:
558 return MqSendRETURN(mqctx);
559}
static enum MkErrorE FINA(MQ_SERVICE_CALL_ARGS)
Definition abrain.c:510
static enum MkErrorE STEP(MQ_SERVICE_CALL_ARGS)
Definition abrain.c:305
static enum MkErrorE EXEC(MQ_SERVICE_CALL_ARGS)
Definition abrain.c:418
static enum MkErrorE PREP(MQ_SERVICE_CALL_ARGS)
Definition abrain.c:428
static enum MkErrorE CLOS(MQ_SERVICE_CALL_ARGS)
Definition abrain.c:520
#define MkErrorSetC_4M(m,...)
#define MkDLogV(x, _debug, printfmt,...)
#define MqSendSTART(...)
+ Here is the caller graph for this function:

◆ PREP()

static enum MkErrorE PREP ( MQ_SERVICE_CALL_ARGS )
static

Definition at line 428 of file abrain.c.

428 {
430 MK_STRN sql,end,type,start;
431 MK_I32 idx;
432 MK_BUF buf;
433
434 // parse prefix
435 MkErrorCheck(MqReadBUF(mqctx,&buf));
436 if (buf->var.type == MK_I32T) {
437 MkErrorCheck(MkBufferGetI32(buf,&idx));
438 MkErrorCheck(IdxFinalize(mqctx, idx));
439 MkErrorCheck(MqReadBUF(mqctx,&buf));
440 } else {
441 idx = brain->prepare_start;
442 }
443 MkErrorCheck(MkBufferGetSTR(buf,&sql));
444 end = sql + buf->storage.size;
445
446 // process values
447 MqSendSTART(mqctx);
448 while (sql != NULL && *sql != '\0') {
449 // get the index
450 for (; idx<DB_PREPARE_MAX && brain->prepStmt[idx]!=NULL; idx++);
451 if (idx >= DB_PREPARE_MAX) {
452 MkErrorSetV_4M (mqctx, __func__, SQLITE_ERROR, "unable to find a free prepare entry - only '%i' entries are allowed.", DB_PREPARE_MAX);
453 goto error;
454 }
455 // find 'in:???' prefix
456 brain->inType[idx] = NULL;
457 brain->inEnd[idx] = NULL;
458 brain->outType[idx] = NULL;
459 brain->outEnd[idx] = NULL;
460 // 1. search for '/' as beginn of comment
461 for (start=sql; start<end && *start != '/' && *start != ';'; start++);
462 // 2. '/*' as 2cnd char
463 if (start == end || *start++ != '/' || *start++ != '*') goto update;
464
465 // find 'in:???' prefix
466 // in1. 'WS' before "TYPE:???"
467 for (; start<end && isspace(*start); start++);
468 // in2. 'in:' the prefix
469 if (start >= end-3 || strncmp(start, "in:", 3)) goto out;
470 start+=3;
471 // in3. 'ASCII' as beginn of comment
472 for (type=start; start<end && isupper(*start); start++);
473 if (start == end) goto out;
474 // in4. we have everything
475 brain->inType[idx] = MkSysStrNDup(MkOBJ(mqctx), type, (start-type));
476 brain->inEnd[idx] = brain->inType[idx] + (start-type);
477 *brain->inEnd[idx] = '\0';
478
479out:
480 // find 'out:???' prefix
481 // out1. 'WS' before "TYPE:???"
482 for (; start<end && isspace(*start); start++);
483 // out2. 'out:' the prefix
484 if (start >= end-4 || strncmp(start, "out:", 4)) goto update;
485 start+=4;
486 // out3. 'ASCII' as beginn of comment
487 for (type=start; start<end && isupper(*start); start++);
488 if (start == end) goto update;
489 // out4. we have everything
490 brain->outType[idx] = MkSysStrNDup(MkOBJ(mqctx), type, (start-type));
491 brain->outEnd[idx] = brain->outType[idx] + (start-type);
492 *brain->outEnd[idx] = '\0';
493
494update:
495 // update the database
496 brain->prepare_start=idx+1;
497 DbErrorCheck(sqlite3_prepare_v2(brain->db, sql, -1, &brain->prepStmt[idx], &sql));
498 MqSendI32(mqctx, idx);
499 }
500error:
501/*
502printLC(brain->inType[idx])
503printLC(brain->inEnd[idx])
504printLC(brain->outType[idx])
505printLC(brain->outEnd[idx])
506*/
507 return MqSendRETURN(mqctx);
508}
#define MkBufferGetSTR(...)
#define MkBufferGetI32(...)
#define MkOBJ(x)
MK_EXTERN MK_STR MkSysStrNDup(MK_OBJ const fmtobj, MK_STRN const str, MK_SIZE const len)
#define MqReadBUF(...)
struct MkBufferS::@5 storage
MK_NUM size
struct MkBufferS::@4 var
enum MkTypeE type
+ Here is the caller graph for this function:

◆ STEP()

static enum MkErrorE STEP ( MQ_SERVICE_CALL_ARGS )
static

Definition at line 305 of file abrain.c.

305 {
307 MK_I32 idx=0;
308 MK_BUF buf;
309 sqlite3_stmt *hdl=NULL;
310 MK_STRN inType=NULL, inEnd=NULL;
311 MK_STRN outType=NULL, outEnd=NULL;
312 enum MkTypeE ntype;
313
314 MkErrorCheck(HdlGet(mqctx, &hdl, &inType, &inEnd, &outType, &outEnd));
315 DbErrorCheck(sqlite3_reset(hdl));
316
317 MqSendSTART(mqctx);
318 while (MqReadItemExists(mqctx)) {
319 idx+=1;
320 MkErrorCheck(MqReadBUF(mqctx,&buf));
321 if (inType && inType < inEnd) {
322 ntype = GetTypeE(*inType);
323 if (buf->var.type != ntype && buf->var.type != MK_STRT) {
324 MkErrorSetV_4M(mqctx,__func__,SQLITE_ERROR,
325 "the buffer type '%c' does not match database type '%c'",
326 MkBufferGetType1(buf), *inType);
327 goto error;
328 }
329 inType++;
330 } else {
331 ntype = buf->var.type;
332 }
333 switch (buf->var.type) {
334 case MK_I8T: DbErrorCheck(sqlite3_bind_int(hdl,idx,buf->storage.first.A->I8)); break;
335 case MK_BOLT: DbErrorCheck(sqlite3_bind_int(hdl,idx,buf->storage.first.A->BOL)); break;
336 case MK_I16T: DbErrorCheck(sqlite3_bind_int(hdl,idx,buf->storage.first.A->I16)); break;
337 case MK_I32T: DbErrorCheck(sqlite3_bind_int(hdl,idx,buf->storage.first.A->I32)); break;
338 case MK_I64T: DbErrorCheck(sqlite3_bind_int64(hdl,idx,buf->storage.first.A->I64)); break;
339 case MK_FLTT: DbErrorCheck(sqlite3_bind_double(hdl,idx,buf->storage.first.A->FLT)); break;
340 case MK_DBLT: DbErrorCheck(sqlite3_bind_double(hdl,idx,buf->storage.first.A->DBL)); break;
341 case MK_STRT:
342 switch (ntype) {
343 case1(MK_I8,sqlite3_bind_int,I8)
344 case1(MK_BOL,sqlite3_bind_int,BOL)
345 case1(MK_I16,sqlite3_bind_int,I16)
346 case1(MK_I32,sqlite3_bind_int,I32)
347 case1(MK_I64,sqlite3_bind_int64,I64)
348 case1(MK_FLT,sqlite3_bind_double,FLT)
349 case1(MK_DBL,sqlite3_bind_double,DBL)
350 case MK_STRT:
351 DbErrorCheck(sqlite3_bind_text (hdl,idx,buf->storage.first.C,(int)buf->storage.size,SQLITE_TRANSIENT));
352 break;
353 case MK_BINT:
354 if (buf->storage.size == 0) {
355 DbErrorCheck (sqlite3_bind_null (hdl,idx));
356 } else {
357 DbErrorCheck (sqlite3_bind_blob (hdl,idx,buf->storage.first.B,(int)buf->storage.size,SQLITE_TRANSIENT));
358 }
359 break;
360 case MK_LSTT:
361 MkErrorSetV_4M (mqctx, __func__, SQLITE_ERROR, "invalid protocoll item '%c'", GetTypeS(ntype));
362 }
363 break;
364 case MK_BINT:
365 if (buf->storage.size == 0) {
366 DbErrorCheck (sqlite3_bind_null (hdl,idx));
367 } else {
368 DbErrorCheck (sqlite3_bind_blob (hdl,idx,buf->storage.first.B,(int)buf->storage.size,SQLITE_TRANSIENT));
369 }
370 break;
371 case MK_LSTT:
372 MkErrorSetV_4M (mqctx, __func__, SQLITE_ERROR, "invalid protocoll item '%c'", GetTypeS(ntype));
373 break;
374 }
375 }
376
377 MK_STRN pos;
378 MqSendSTART(mqctx);
379 while (true) {
380 switch (sqlite3_step(hdl)) {
381 case SQLITE_ROW: {
382 MqSendL_START(mqctx);
383 for (idx=0,pos=outType; idx<sqlite3_column_count(hdl); idx++,pos++) {
384 ntype = pos && pos < outEnd ? GetTypeE(*pos) : GetTypeD(hdl,idx);
385 switch (sqlite3_column_type(hdl,idx)) {
386 case SQLITE_INTEGER:
387 case SQLITE_FLOAT:
388 case SQLITE_NULL:
389 MkErrorCheck(GetFromDBnat(mqctx, ntype, hdl, idx));
390 break;
391 case SQLITE_BLOB:
392 case SQLITE_TEXT:
393 MkErrorCheck(GetFromDBary(mqctx, ntype, hdl, idx));
394 break;
395 }
396 }
397 MqSendL_END(mqctx);
398 continue;
399 break;
400 }
401 case SQLITE_DONE:
402 goto error;
403 case SQLITE_LOCKED:
404 case SQLITE_BUSY:
405 continue;
406 default:
407 MkErrorSetC_4M (mqctx, sqlite3_errmsg(brain->db), __func__, sqlite3_extended_errcode(brain->db));
408 DbErrorCheck(sqlite3_reset(hdl));
409 goto error;
410 }
411 }
412
413error:
414 sqlite3_reset(hdl);
415 return MqSendRETURN(mqctx);
416}
#define GetFromDBary(...)
Definition abrain.c:303
static enum MkTypeE GetTypeE(MK_STRB t)
Definition abrain.c:194
static enum MkTypeE GetTypeD(sqlite3_stmt *hdl, MK_I32 idx)
Definition abrain.c:226
#define GetFromDBnat(...)
Definition abrain.c:277
#define HdlGet(...)
Definition abrain.c:167
#define case1(t, f, c)
Definition abrain.c:246
#define MkBufferGetType1(...)
MkTypeE
MQ_EXTERN bool MqReadItemExists(MQ_CTX const ctx) MK_ATTR_HDL
#define MqSendL_START(...)
#define MqSendL_END(...)
union MkBufferU first
MK_STRN C
MK_ATO * A
MK_BIN B
+ Here is the caller graph for this function:

Variable Documentation

◆ BrainTT

MK_TYP BrainTT = NULL
static

link to the MqErrorS object

Definition at line 30 of file abrain.c.