source: trunk/tools/database/db.cpp@ 2776

Last change on this file since 2776 was 2776, checked in by bird, 26 years ago

Bugfixes. Nearly there now!

File size: 56.8 KB
Line 
1/* $Id: db.cpp,v 1.10 2000-02-14 17:18:31 bird Exp $ *
2 *
3 * DB - contains all database routines.
4 *
5 * Copyright (c) 1999 knut st. osmundsen
6 *
7 */
8
9/*******************************************************************************
10* Defined Constants *
11*******************************************************************************/
12#define CheckLogContinue(sprintfargs) \
13 if (rc < 0) \
14 { \
15 if (pszError[1] == '\xFE') \
16 { \
17 strcat(pszError, "\n\t"); \
18 pszError += 2; \
19 } \
20 sprintf sprintfargs; \
21 ulRc++; \
22 pszError += strlen(pszError); \
23 pszError[1] = '\xFE'; \
24 } \
25 rc=rc
26
27
28#define CheckFKError(table, msg) \
29 pres2 = mysql_store_result(pmysql);\
30 if (rc < 0 || pres2 == NULL || \
31 mysql_num_rows(pres2) == 0) \
32 { \
33 if (pszError[1] == '\xFE') \
34 { \
35 strcat(pszError, "\n\t"); \
36 pszError += 2; \
37 } \
38 sprintf(pszError, table ":" \
39 msg \
40 " (refcode=%s) " \
41 "(sql=%s)", \
42 row1[0], \
43 pszQuery); \
44 ulRc++; \
45 pszError += strlen(pszError); \
46 pszError[1] = '\xFE'; \
47 } \
48 if (pres2 != NULL) \
49 mysql_free_result(pres2)
50
51
52/*******************************************************************************
53* Header Files *
54*******************************************************************************/
55#define INCL_DOSMISC
56#include <os2.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <string.h>
60#include <memory.h>
61#include <signal.h>
62#include <assert.h>
63#include <limits.h>
64#include <mysql.h>
65
66#include "db.h"
67
68
69/*@Global***********************************************************************
70* Global Variables *
71*******************************************************************************/
72static MYSQL mysql;
73static MYSQL *pmysql = NULL;
74
75
76/*@IntFunc**********************************************************************
77* Internal Functions *
78*******************************************************************************/
79static long getvalue(int iField, MYSQL_ROW pRow);
80static unsigned long CheckAuthorError(char * &pszError, const char *pszFieldName, const char *pszFieldValue, const char *pszQuery);
81static unsigned long logDbError(char * &pszError, const char *pszQuery);
82#ifndef DLL
83 extern "C" void dbHandler(int sig);
84#endif
85
86
87/**
88 * Gets the descriptions of the last database error.
89 * @returns Readonly string.
90 */
91char * _System dbGetLastErrorDesc(void)
92{
93 return mysql_error(&mysql);
94}
95
96
97/**
98 * Connects to local database.
99 * @returns Success indicator, TRUE / FALSE.
100 * @param pszDatabase Name of database to use.
101 */
102BOOL _System dbConnect(const char *pszHost, const char *pszUser, const char *pszPassword, const char *pszDatabase)
103{
104 BOOL fRet = FALSE;
105 #ifndef DLL
106 static fHandler = FALSE;
107 /* signal handler */
108 if (!fHandler)
109 {
110 if ( SIG_ERR == signal(SIGBREAK, dbHandler)
111 || SIG_ERR == signal(SIGINT, dbHandler)
112 || SIG_ERR == signal(SIGTERM, dbHandler)
113 || SIG_ERR == signal(SIGABRT, dbHandler)
114 || SIG_ERR == signal(SIGSEGV, dbHandler)
115 || SIG_ERR == signal(SIGILL, dbHandler)
116 )
117 fprintf(stderr, "Error installing signalhandler...");
118 else
119 fHandler = TRUE;
120 }
121 #endif
122
123 /* connect to server */
124 memset(&mysql, 0, sizeof(mysql));
125 pmysql = mysql_connect(&mysql, pszHost, pszUser, pszPassword);
126 if (pmysql != NULL)
127 {
128 /* connect to database */
129 fRet = mysql_select_db(pmysql, pszDatabase) >= 0;
130 if (fRet)
131 mysql_refresh(pmysql, REFRESH_TABLES);
132 }
133
134 return fRet;
135}
136
137
138/**
139 * Disconnects from database.
140 * @returns Success indicator. TRUE / FALSE.
141 */
142BOOL _System dbDisconnect(void)
143{
144 if (pmysql != NULL)
145 {
146 mysql_refresh(pmysql, REFRESH_TABLES);
147 mysql_close(pmysql);
148 pmysql = NULL;
149 }
150 return TRUE;
151}
152
153/**
154 * Gets the refid for the give dll name.
155 * @returns Dll refid. -1 on error.
156 * @param pszDllName Dll name.
157 */
158signed short _System dbGetDll(const char *pszDllName)
159{
160 int rc;
161 char szQuery[256];
162 MYSQL_RES * pres;
163
164 sprintf(&szQuery[0], "SELECT refcode FROM dll WHERE name = '%s'\n", pszDllName);
165 rc = mysql_query(pmysql, &szQuery[0]);
166 pres = mysql_store_result(pmysql);
167
168 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
169 rc = (int)getvalue(0, mysql_fetch_row(pres));
170 else
171 rc = -1;
172 mysql_free_result(pres);
173 return (short)rc;
174}
175
176
177/**
178 * Count the function in a given dll.
179 * @returns Number of functions. -1 on error.
180 * @param usDll Dll refcode.
181 * @param fNotAliases TRUE: don't count aliased functions.
182 */
183signed long _System dbCountFunctionInDll(signed long ulDll, BOOL fNotAliases)
184{
185 signed long rc;
186 char szQuery[256];
187 MYSQL_RES * pres;
188
189 if (ulDll >= 0)
190 {
191 sprintf(&szQuery[0], "SELECT count(refcode) FROM function WHERE dll = %ld\n", ulDll);
192 if (fNotAliases)
193 strcat(&szQuery[0], " AND aliasfn < 0");
194 rc = mysql_query(pmysql, &szQuery[0]);
195 pres = mysql_store_result(pmysql);
196
197 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
198 rc = (int)getvalue(0, mysql_fetch_row(pres));
199 else
200 rc = -1;
201 mysql_free_result(pres);
202 }
203 else
204 rc = -1;
205 return rc;
206}
207
208
209
210/**
211 * Checks if dll exists. If not exists the dll is inserted.
212 * @returns Dll refcode. -1 on errors.
213 * @param pszDll Dll name.
214 * @remark This search must be case insensitive.
215 * (In the mysql-world everything is case insensitive!)
216 */
217signed short _System dbCheckInsertDll(const char *pszDll)
218{
219 int rc;
220 char szQuery[256];
221 MYSQL_RES * pres;
222
223 /* try find match */
224 sprintf(&szQuery[0], "SELECT refcode, name FROM dll WHERE name = '%s'\n", pszDll);
225 rc = mysql_query(pmysql, &szQuery[0]);
226 pres = mysql_store_result(pmysql);
227
228 /* not found? - insert dll */
229 if (rc < 0 || pres == NULL || mysql_num_rows(pres) == 0)
230 {
231 mysql_free_result(pres);
232
233 sprintf(&szQuery[0], "INSERT INTO dll(name) VALUES('%s')\n", pszDll);
234 rc = mysql_query(pmysql, &szQuery[0]);
235
236 /* select row to get refcode */
237 sprintf(&szQuery[0], "SELECT refcode, name FROM dll WHERE name = '%s'\n", pszDll);
238 rc = mysql_query(pmysql, &szQuery[0]);
239 pres = mysql_store_result(pmysql);
240 }
241
242 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
243 rc = (int)getvalue(0, mysql_fetch_row(pres));
244 else
245 rc = -1;
246 mysql_free_result(pres);
247
248 return (short)rc;
249}
250
251
252/**
253 * Simple select for a long value.
254 * @returns long value
255 * @param pszTable From part.
256 * @param pszGetColumn Name of column to retreive.
257 * @param pszMatch1 Match column/expression
258 * @param pszMatchValue1 Match value.
259 * @remark Dirty! Don't use this!
260 */
261unsigned short _System dbGet(const char *pszTable, const char *pszGetColumn,
262 const char *pszMatch1, const char *pszMatchValue1)
263{
264 int rc;
265 char szQuery[256];
266 MYSQL_RES *pres;
267
268 /* try find match */
269 sprintf(&szQuery[0], "SELECT %s FROM %s WHERE %s = '%s'\n",
270 pszGetColumn, pszTable, pszMatch1, pszMatchValue1);
271 rc = mysql_query(pmysql, &szQuery[0]);
272 pres = mysql_store_result(pmysql);
273
274 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
275 rc = (int)getvalue(0, mysql_fetch_row(pres));
276 else
277 rc = -1;
278 mysql_free_result(pres);
279
280 return (short)rc;
281}
282
283
284/**
285 * Updates or inserts a function name into the database.
286 * @returns Success indicator. TRUE / FALSE.
287 * @param usDll Dll refcode.
288 * @param pszFunction Function name.
289 * @param pszIntFunction Internal function name. (required!)
290 * @param ulOrdinal Ordinal value.
291 * @param fIgnoreOrdinal Do not update ordinal value.
292 */
293BOOL _System dbInsertUpdateFunction(unsigned short usDll,
294 const char *pszFunction, const char *pszIntFunction,
295 unsigned long ulOrdinal, BOOL fIgnoreOrdinal)
296{
297 int rc;
298 long lFunction = -1;
299 char szQuery[256];
300 MYSQL_RES *pres;
301
302 /* when no internal name fail! */
303 if (pszIntFunction == NULL || *pszIntFunction == '\0')
304 return FALSE;
305
306 /* try find function */
307 sprintf(&szQuery[0], "SELECT refcode, intname FROM function WHERE dll = %d AND name = '%s'", usDll, pszFunction);
308 rc = mysql_query(pmysql, &szQuery[0]);
309 pres = mysql_store_result(pmysql);
310 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) != 0)
311 { /* update function (function is found) */
312 MYSQL_ROW parow;
313 if (mysql_num_rows(pres) > 1)
314 {
315 fprintf(stderr, "internal database integrity error(%s): More function by the same name for the same dll. "
316 "usDll = %d, pszFunction = %s\n", __FUNCTION__, usDll, pszFunction);
317 return FALSE;
318 }
319
320 parow = mysql_fetch_row(pres);
321 if (parow != NULL)
322 lFunction = getvalue(0, parow);
323 mysql_free_result(pres);
324
325 if (strcmp(parow[1], pszIntFunction) != 0)
326 {
327 sprintf(&szQuery[0], "UPDATE function SET intname = '%s' WHERE refcode = %ld",
328 pszIntFunction, lFunction);
329 rc = mysql_query(pmysql, &szQuery[0]);
330 }
331
332 if (rc >= 0 && !fIgnoreOrdinal)
333 {
334 sprintf(&szQuery[0], "UPDATE function SET ordinal = %ld WHERE refcode = %ld",
335 ulOrdinal, lFunction);
336 rc = mysql_query(pmysql, &szQuery[0]);
337 }
338
339 }
340 else
341 { /* insert */
342 sprintf(&szQuery[0], "INSERT INTO function(dll, name, intname, ordinal) VALUES(%d, '%s', '%s', %ld)",
343 usDll, pszFunction, pszIntFunction, ulOrdinal);
344 rc = mysql_query(pmysql, &szQuery[0]);
345 }
346
347 return rc >= 0;
348}
349
350
351/**
352 * Get a long value.
353 * @returns Number value of pRow[iField]. -1 on error.
354 * @param iField Index into pRow.
355 * @param pRow Pointer to array (of string pointers).
356 */
357static long getvalue(int iField, MYSQL_ROW papszRow)
358{
359 if (papszRow[iField] != NULL)
360 return atol((char*)papszRow[iField]);
361
362 return -1;
363}
364
365
366#if 0
367/*
368 * Stubs used while optimizing sqls.
369 */
370int mysql_query1(MYSQL *mysql, const char *q)
371{ return mysql_query(mysql, q); }
372int mysql_query2(MYSQL *mysql, const char *q)
373{ return mysql_query(mysql, q); }
374int mysql_query3(MYSQL *mysql, const char *q)
375{ return mysql_query(mysql, q); }
376int mysql_query4(MYSQL *mysql, const char *q)
377{ return mysql_query(mysql, q); }
378int mysql_query5(MYSQL *mysql, const char *q)
379{ return mysql_query(mysql, q); }
380int mysql_query6(MYSQL *mysql, const char *q)
381{ return mysql_query(mysql, q); }
382
383#else
384
385#define mysql_query1 mysql_query
386#define mysql_query2 mysql_query
387#define mysql_query3 mysql_query
388#define mysql_query4 mysql_query
389#define mysql_query5 mysql_query
390#define mysql_query6 mysql_query
391
392#endif
393
394
395
396/**
397 * Find occurences of a function, given by internal name.
398 * @returns success indicator, TRUE / FALSE.
399 * @param pszFunctionName
400 * @param pFnFindBuf
401 * @param lDll
402 * @sketch 1) Get functions for this dll(if given).
403 * 2) Get functions which aliases the functions found in (1).
404 * 3) Get new aliases by intname
405 * 4) Get new aliases by name
406 * 5) Update all functions from (1) to have aliasfn -2 (DONTMIND)
407 * 6) Update all functions from (3) and (4) to alias the first function from 1.
408 */
409BOOL _System dbFindFunction(const char *pszFunctionName, PFNFINDBUF pFnFindBuf, signed long lDll)
410{
411 MYSQL_RES *pres;
412 MYSQL_ROW row;
413 int rc;
414 char szQuery[1024];
415
416 /*
417 * 1) Get functions for this dll(if given).
418 */
419 if (lDll < 0)
420 sprintf(&szQuery[0], "SELECT refcode, dll, aliasfn, name FROM function WHERE intname = '%s'",
421 pszFunctionName);
422 else
423 sprintf(&szQuery[0], "SELECT refcode, dll, aliasfn, name FROM function "
424 "WHERE intname = '%s' AND dll = %ld",
425 pszFunctionName, lDll);
426
427 rc = mysql_query1(pmysql, &szQuery[0]);
428 if (rc >= 0)
429 {
430 pres = mysql_store_result(pmysql);
431 if (pres != NULL)
432 {
433 char szFnName[NBR_FUNCTIONS][80];
434
435 pFnFindBuf->cFns = 0;
436 while ((row = mysql_fetch_row(pres)) != NULL)
437 {
438 pFnFindBuf->alRefCode[pFnFindBuf->cFns] = atol(row[0]);
439 pFnFindBuf->alDllRefCode[pFnFindBuf->cFns] = atol(row[1]);
440 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = atol(row[2]);
441 strcpy(szFnName[pFnFindBuf->cFns], row[3]);
442
443 /* next */
444 pFnFindBuf->cFns++;
445 }
446 mysql_free_result(pres);
447
448 /* alias check and fix */
449 if (lDll >= 0 && pFnFindBuf->cFns != 0)
450 {
451 int cFnsThisDll, cFnsAliasesAndThisDll, i, f;
452
453 /*
454 * 2) Get functions which aliases the functions found in (1).
455 */
456 cFnsThisDll = (int)pFnFindBuf->cFns;
457 strcpy(&szQuery[0], "SELECT refcode, dll, aliasfn, name FROM function WHERE aliasfn IN (");
458 for (i = 0; i < cFnsThisDll; i++)
459 {
460 if (i > 0) strcat(&szQuery[0], " OR ");
461 sprintf(&szQuery[strlen(szQuery)], "(%ld)", pFnFindBuf->alRefCode[i]);
462 }
463 strcat(&szQuery[0], ")");
464
465 rc = mysql_query2(pmysql, &szQuery[0]);
466 if (rc >= 0)
467 {
468 pres = mysql_store_result(pmysql);
469 if (pres != NULL)
470 {
471 while ((row = mysql_fetch_row(pres)) != NULL)
472 {
473 pFnFindBuf->alRefCode[pFnFindBuf->cFns] = atol(row[0]);
474 pFnFindBuf->alDllRefCode[pFnFindBuf->cFns] = atol(row[1]);
475 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = atol(row[2]);
476 strcpy(szFnName[pFnFindBuf->cFns], row[3]);
477
478 /* next */
479 pFnFindBuf->cFns++;
480 }
481 mysql_free_result(pres);
482
483 /*
484 * 3) Get new aliases by intname
485 */
486 cFnsAliasesAndThisDll = (int)pFnFindBuf->cFns;
487 sprintf(&szQuery[0], "SELECT refcode, dll, aliasfn FROM function "
488 "WHERE aliasfn = (-1) AND dll <> %ld AND (intname = '%s'",
489 lDll, pszFunctionName);
490 for (i = 0; i < cFnsAliasesAndThisDll; i++)
491 sprintf(&szQuery[strlen(&szQuery[0])], " OR intname = '%s'", szFnName[i]);
492 strcat(&szQuery[0], ")");
493
494 rc = mysql_query3(pmysql, &szQuery[0]);
495 if (rc >= 0)
496 {
497 pres = mysql_store_result(pmysql);
498 if (pres != NULL)
499 {
500 while ((row = mysql_fetch_row(pres)) != NULL)
501 {
502 pFnFindBuf->alRefCode[pFnFindBuf->cFns] = atol(row[0]);
503 pFnFindBuf->alDllRefCode[pFnFindBuf->cFns] = atol(row[1]);
504 if (row[2] != NULL)
505 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = atol(row[2]);
506 else
507 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = ALIAS_NULL;
508
509 /* next */
510 pFnFindBuf->cFns++;
511 }
512 mysql_free_result(pres);
513
514
515 /*
516 * 4) Get new aliases by name
517 */
518 sprintf(&szQuery[0], "SELECT refcode, dll, aliasfn FROM function "
519 "WHERE aliasfn = (-1) AND dll <> %ld AND (name = '%s'",
520 lDll, pszFunctionName);
521 for (i = 0; i < cFnsAliasesAndThisDll; i++)
522 sprintf(&szQuery[strlen(&szQuery[0])], " OR name = '%s'", szFnName[i]);
523 strcat(&szQuery[0], ")");
524
525 rc = mysql_query4(pmysql, &szQuery[0]);
526 if (rc >= 0)
527 {
528 pres = mysql_store_result(pmysql);
529 if (pres != NULL)
530 {
531 while ((row = mysql_fetch_row(pres)) != NULL)
532 {
533 pFnFindBuf->alRefCode[pFnFindBuf->cFns] = atol(row[0]);
534 pFnFindBuf->alDllRefCode[pFnFindBuf->cFns] = atol(row[1]);
535 if (row[2] != NULL)
536 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = atol(row[2]);
537 else
538 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = ALIAS_NULL;
539
540 /* next */
541 pFnFindBuf->cFns++;
542 }
543 mysql_free_result(pres);
544
545 /*
546 * 5) Update all functions from (1) to have aliasfn -2 (DONTMIND)
547 */
548 sprintf(&szQuery[0], "UPDATE function SET aliasfn = (-2) "
549 "WHERE refcode IN (",
550 lDll, pszFunctionName);
551 for (f = 0, i = 0; i < cFnsThisDll; i++)
552 if (pFnFindBuf->alAliasFn[i] != ALIAS_DONTMIND)
553 sprintf(&szQuery[strlen(&szQuery[0])],
554 f++ != 0 ? ", %ld" : "%ld", pFnFindBuf->alRefCode[i]);
555 strcat(&szQuery[0], ") AND aliasfn <> (-2)");
556 if (f > 0)
557 rc = mysql_query5(pmysql, &szQuery[0]);
558 else
559 rc = 0;
560 if (rc >= 0 && cFnsAliasesAndThisDll < pFnFindBuf->cFns)
561 {
562 /*
563 * 6) Update all functions from (3) and (4) to alias the first function from 1.
564 */
565 sprintf(&szQuery[0], "UPDATE function SET aliasfn = (%ld) "
566 "WHERE aliasfn = (-1) AND refcode IN (",
567 pFnFindBuf->alRefCode[0]);
568 for (i = cFnsAliasesAndThisDll; i < pFnFindBuf->cFns; i++)
569 {
570 sprintf(&szQuery[strlen(&szQuery[0])],
571 i > cFnsAliasesAndThisDll ? ", %ld" : "%ld", pFnFindBuf->alRefCode[i]);
572 }
573 strcat(&szQuery[0], ")");
574 rc = mysql_query6(pmysql, &szQuery[0]);
575 } /* query 5 */
576 }
577 } /* query 4 */
578 }
579 } /* query 3 */
580 }
581 } /* query 2 */
582 }
583 } /* query 1 */
584 else
585 rc = -1;
586 }
587
588 return rc >= 0;
589}
590
591
592/**
593 * Finds the refcode for an author, if the author exists.
594 * @returns Author 'refcode'.
595 * @param pszAuthor String which holds the identifier of an author.
596 * This doesn't have to be the name. Initials, alias and email
597 * is also searched.
598 */
599signed long _System dbFindAuthor(const char *pszAuthor)
600{
601 signed long refcode = -1;
602 MYSQL_RES *pres;
603 char szQuery[256];
604
605 sprintf(&szQuery[0],
606 "SELECT refcode FROM author "
607 "WHERE name = '%s' OR "
608 " initials = '%s' OR "
609 " alias = '%s' OR "
610 " email = '%s'",
611 pszAuthor, pszAuthor, pszAuthor, pszAuthor);
612 if (mysql_query(pmysql, &szQuery[0]) >= 0)
613 {
614 pres = mysql_store_result(pmysql);
615 if (pres != NULL)
616 {
617 MYSQL_ROW parow;
618
619 /* integrety check */
620 if (mysql_num_rows(pres) > 1)
621 fprintf(stderr, "Integrety: author '%s' is not unique!\n", pszAuthor);
622 parow = mysql_fetch_row(pres);
623 if (parow != NULL)
624 refcode = getvalue(0, parow);
625
626 mysql_free_result(pres);
627 }
628 }
629
630 return refcode;
631}
632
633
634/**
635 * Gets the state of a function.
636 * @returns state code. On error -1.
637 * @param lRefCode Function refcode.
638 */
639signed long _System dbGetFunctionState(signed long lRefCode)
640{
641 signed long lState = -1;
642 MYSQL_RES *pres;
643 char szQuery[128];
644
645 sprintf(&szQuery[0], "SELECT state FROM function WHERE refcode = %ld", lRefCode);
646 if (mysql_query(pmysql, &szQuery[0]) >= 0)
647 {
648 pres = mysql_store_result(pmysql);
649 if (pres != NULL)
650 {
651 MYSQL_ROW parow = mysql_fetch_row(pres);
652 if (parow != NULL)
653 lState = getvalue(0, parow);
654 mysql_free_result(pres);
655 }
656 }
657
658 return lState;
659}
660
661#if 1
662/*
663 * Stubs used while optimizing sqls.
664 */
665int mysql_queryu1(MYSQL *mysql, const char *q)
666{ return mysql_query(mysql, q); }
667int mysql_queryu2(MYSQL *mysql, const char *q)
668{ return mysql_query(mysql, q); }
669int mysql_queryu3(MYSQL *mysql, const char *q)
670{ return mysql_query(mysql, q); }
671int mysql_queryu4(MYSQL *mysql, const char *q)
672{ return mysql_query(mysql, q); }
673int mysql_queryu5(MYSQL *mysql, const char *q)
674{ return mysql_query(mysql, q); }
675int mysql_queryu6(MYSQL *mysql, const char *q)
676{ return mysql_query(mysql, q); }
677int mysql_queryu7(MYSQL *mysql, const char *q)
678{ return mysql_query(mysql, q); }
679int mysql_queryu8(MYSQL *mysql, const char *q)
680{ return mysql_query(mysql, q); }
681#else
682#define mysql_queryu1 mysql_query
683#define mysql_queryu2 mysql_query
684#define mysql_queryu3 mysql_query
685#define mysql_queryu4 mysql_query
686#define mysql_queryu5 mysql_query
687#define mysql_queryu6 mysql_query
688#define mysql_queryu7 mysql_query
689#define mysql_queryu8 mysql_query
690#endif
691
692/**
693 * Updates function information.
694 * @returns number of errors.
695 * @param pFnDesc Function description struct.
696 * @param lDll Dll which we are working at.
697 * @param pszError Buffer for error messages
698 * @result on error(s) pszError will hold information about the error(s).
699 */
700unsigned long _System dbUpdateFunction(PFNDESC pFnDesc, signed long lDll, char *pszError)
701{
702 MYSQL_RES * pres;
703 MYSQL_ROW row;
704 char szQuery[512];
705 char * pszQuery = &szQuery[0];
706 long lCurrentState;
707 int i,k,rc;
708 unsigned long ulRc = 0;
709
710 for (k = 0; k < pFnDesc->cRefCodes; k++)
711 {
712 BOOL f = FALSE;
713
714 /*
715 * Set updated flag
716 */
717 sprintf(pszQuery, "UPDATE function SET updated = updated + 1 WHERE refcode = %ld",
718 pFnDesc->alRefCode[k]);
719 rc = mysql_queryu1(pmysql, &szQuery[0]);
720
721
722 /*
723 * Get current status
724 */
725 lCurrentState = dbGetFunctionState(pFnDesc->alRefCode[k]);
726 if (lCurrentState == -1)
727 {
728 strcpy(pszError, dbGetLastErrorDesc());
729 return 1;
730 }
731
732
733 /*
734 * Update function table first
735 */
736 strcpy(pszQuery, "UPDATE function SET ");
737 pszQuery += strlen(pszQuery);
738 if (pFnDesc->lStatus != 99 || lCurrentState == 0)
739 {
740 sprintf(pszQuery, "state = %ld ", pFnDesc->lStatus);
741 f = TRUE;
742 }
743 pszQuery += strlen(pszQuery);
744
745 if (pFnDesc->pszReturnType != NULL)
746 {
747 if (f) strcat(pszQuery, ", ");
748 sprintf(pszQuery + strlen(pszQuery), "return = '%s' ", pFnDesc->pszReturnType);
749 pszQuery += strlen(pszQuery);
750 f = TRUE;
751 }
752
753 if (f)
754 {
755 sprintf(pszQuery + strlen(pszQuery), "WHERE refcode = %ld", pFnDesc->alRefCode[k]);
756 rc = mysql_queryu2(pmysql, &szQuery[0]);
757 if (rc < 0)
758 {
759 sprintf(pszError, "Updating functiontable failed with error: %s - (sql=%s) ",
760 dbGetLastErrorDesc(), &szQuery[0]);
761 pszError += strlen(pszError) - 1;
762 ulRc++;
763 }
764 }
765
766
767 /*
768 * Parameters
769 */
770 pszQuery = &szQuery[0];
771 sprintf(pszQuery, "SELECT count(*) FROM parameter WHERE function = %ld", pFnDesc->alRefCode[k]);
772 rc = mysql_queryu3(pmysql, pszQuery);
773 if (rc >= 0)
774 {
775 pres = mysql_store_result(pmysql);
776 if (pres != NULL)
777 row = mysql_fetch_row(pres);
778 if (pres != NULL && row != NULL && mysql_num_rows(pres) == 1)
779 {
780 if (atol(row[0]) == pFnDesc->cParams)
781 { /* update parameters */
782 for (i = 0; i < pFnDesc->cParams; i++)
783 {
784 sprintf(pszQuery, "UPDATE parameter SET type = '%s', name = '%s' "
785 "WHERE function = (%ld) AND sequencenbr = (%ld)",
786 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
787 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : "",
788 pFnDesc->alRefCode[k], i
789 );
790 rc = mysql_queryu4(pmysql, pszQuery);
791 if (rc < 0)
792 {
793 if (*pszError == ' ')
794 strcpy(pszError++, "\n\t");
795 sprintf(pszError, "Updateing parameter %i failed with error: %s - (sql=%s) ",
796 i, dbGetLastErrorDesc(), pszQuery);
797 pszError += strlen(pszError) - 1;
798 ulRc++;
799 }
800 }
801 }
802 else
803 {
804 if (atol(row[0]) != 0)
805 { /* delete old parameters */
806 sprintf(pszQuery, "DELETE FROM parameter WHERE function = %ld", pFnDesc->alRefCode[k]);
807 rc = mysql_queryu5(pmysql, pszQuery);
808 if (rc < 0)
809 {
810 if (*pszError == ' ')
811 strcpy(pszError++, "\n\t");
812 sprintf(pszError, "Deleting old parameters failed with error: %s - (sql=%s) ",
813 dbGetLastErrorDesc(), pszQuery);
814 pszError += strlen(pszError) - 1;
815 ulRc++;
816 }
817 }
818
819 /* insert parameters */
820 for (i = 0; i < pFnDesc->cParams; i++)
821 {
822 sprintf(pszQuery, "INSERT INTO parameter(function, sequencenbr, type, name) "
823 "VALUES (%ld, %d, '%s', '%s')",
824 pFnDesc->alRefCode[k], i,
825 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
826 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : ""
827 );
828 rc = mysql_queryu6(pmysql, pszQuery);
829 if (rc < 0)
830 {
831 if (*pszError == ' ')
832 strcpy(pszError++, "\n\t");
833 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
834 i, dbGetLastErrorDesc(), pszQuery);
835 pszError += strlen(pszError) - 1;
836 ulRc++;
837 }
838 }
839 }
840 }
841 else
842 {
843 if (*pszError == ' ')
844 strcpy(pszError++, "\n\t");
845 sprintf(pszError, "failed to store result or to fetch a row , error: %s - (sql=%s) ",
846 dbGetLastErrorDesc(), pszQuery);
847 pszError += strlen(pszError) - 1;
848 ulRc++;
849 }
850 }
851 else
852 {
853 if (*pszError == ' ')
854 strcpy(pszError++, "\n\t");
855 sprintf(pszError, "Failed querying number of parameters, error: %s - (sql=%s) ",
856 dbGetLastErrorDesc(), pszQuery);
857 pszError += strlen(pszError) - 1;
858 ulRc++;
859 }
860
861
862 /*
863 * Authors
864 */
865 sprintf(pszQuery, "DELETE FROM fnauthor WHERE function = %ld", pFnDesc->alRefCode[k]);
866 rc = mysql_queryu7(pmysql, pszQuery);
867 if (rc < 0)
868 {
869 if (*pszError == ' ')
870 strcpy(pszError++, "\n\t");
871 sprintf(pszError, "Deleting old authors failed with error: %s - (sql=%s) ",
872 dbGetLastErrorDesc(), pszQuery);
873 pszError += strlen(pszError) - 1;
874 ulRc++;
875 }
876
877 for (i = 0; i < pFnDesc->cAuthors; i++)
878 {
879 if (pFnDesc->alAuthorRefCode[i] == -1)
880 continue;
881 sprintf(pszQuery, "INSERT INTO fnauthor(author, function) "
882 "VALUES (%ld, %ld)",
883 pFnDesc->alAuthorRefCode[i], pFnDesc->alRefCode[k]);
884 rc = mysql_queryu8(pmysql, pszQuery);
885 if (rc < 0)
886 {
887 if (*pszError == ' ')
888 strcpy(pszError++, "\n\t");
889 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
890 i, dbGetLastErrorDesc(), pszQuery);
891 pszError += strlen(pszError) - 1;
892 ulRc++;
893 }
894 }
895 } /* for */
896
897 lDll = lDll;
898 return ulRc;
899}
900
901
902/**
903 * Updates the history tables.
904 * @returns Number of signals/errors.
905 * @param pszError Pointer to buffer which will hold the error messages.
906 * @remark This should be called whenever updates have been completed.
907 */
908unsigned long _System dbCreateHistory(char *pszError)
909{
910 unsigned long ulRc = 0;
911 MYSQL_RES *pres;
912 MYSQL_ROW row;
913 char szQuery[256];
914 char *pszQuery = &szQuery[0];
915 int rc;
916 char szCurDt[20] = {0}; /*yyyy-mm-dd\0*/
917
918 mysql_refresh(pmysql, REFRESH_TABLES);
919
920 /* get currentdate - just in case the date changes between the delete and the update is completed. */
921 strcpy(pszQuery, "SELECT CURDATE()");
922 rc = mysql_query(pmysql, pszQuery);
923 pres = mysql_use_result(pmysql);
924 if (rc >= 0 && pres != NULL)
925 {
926 row = mysql_fetch_row(pres);
927 if (row != NULL && mysql_num_rows(pres) == 1)
928 {
929 strcpy(&szCurDt[0], row[0]);
930 while (mysql_fetch_row(pres) != NULL)
931 pres=pres;
932
933 /* delete - all rows on this date in the history tables */
934 sprintf(pszQuery, "DELETE FROM historydll WHERE date = '%s'", &szCurDt[0]);
935 rc = mysql_query(pmysql, pszQuery);
936 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
937
938 sprintf(pszQuery, "DELETE FROM historyapigroup WHERE date = '%s'", &szCurDt[0]);
939 rc = mysql_query(pmysql, pszQuery);
940 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
941
942 sprintf(pszQuery, "DELETE FROM historydlltotal WHERE date = '%s'", &szCurDt[0]);
943 rc = mysql_query(pmysql, pszQuery);
944 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
945
946 sprintf(pszQuery, "DELETE FROM historyapigrouptotal WHERE date = '%s'", &szCurDt[0]);
947 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
948
949 /* insert new stats */
950 sprintf(pszQuery, "INSERT INTO historydll(dll, state, date, count) "
951 "SELECT dll, state, '%s', count(*) FROM function GROUP BY dll, state",
952 &szCurDt[0]);
953 rc = mysql_query(pmysql, pszQuery);
954 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
955
956 sprintf(pszQuery, "INSERT INTO historyapigroup(apigroup, state, date, count) "
957 "SELECT dll, state, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
958 "GROUP BY apigroup, state",
959 &szCurDt[0]);
960 rc = mysql_query(pmysql, pszQuery);
961 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
962
963 /* inserting new totals */
964 sprintf(pszQuery, "INSERT INTO historydlltotal(dll, date, totalcount) "
965 "SELECT dll, '%s', count(*) FROM function GROUP BY dll",
966 &szCurDt[0]);
967 rc = mysql_query(pmysql, pszQuery);
968 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
969
970 sprintf(pszQuery, "INSERT INTO historyapigrouptotal(apigroup, date, totalcount) "
971 "SELECT apigroup, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
972 "GROUP BY apigroup",
973 &szCurDt[0]);
974 rc = mysql_query(pmysql, pszQuery);
975 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
976 }
977 else
978 {
979 sprintf(pszError, "error getting current date (row == NULL): %s - (sql=%s) ",
980 dbGetLastErrorDesc(), pszQuery);
981 ulRc++;
982 }
983 }
984 else
985 {
986 sprintf(pszError, "error getting current date: %s - (sql=%s) ",
987 dbGetLastErrorDesc(), pszQuery);
988 ulRc++;
989 }
990
991 mysql_refresh(pmysql, REFRESH_TABLES);
992
993 return ulRc;
994}
995
996
997/**
998 * Check that database integrety is ok. Verfies foreign keys.
999 * @returns numbers of errors.
1000 * @param pszError Very large buffer which will hold error messges (if any).
1001 * @sketch
1002 * @remark current versions of mysql don't support 'SELECT ... WHERE id NOT IN(SELECT id FROM table)'
1003 */
1004unsigned long _System dbCheckIntegrity(char *pszError)
1005{
1006 char szQuery[384];
1007 char *pszQuery = &szQuery[0];
1008 MYSQL_RES *pres1;
1009 MYSQL_RES *pres2;
1010 MYSQL_ROW row1;
1011 int rc;
1012 unsigned long ulRc = 0;
1013
1014 mysql_refresh(pmysql, REFRESH_TABLES);
1015
1016 /* foreign keys in function table */
1017 strcpy(pszQuery, "SELECT refcode, dll, state, apigroup FROM function");
1018 rc = mysql_query(pmysql, pszQuery);
1019 if (rc >= 0)
1020 {
1021 pres1 = mysql_store_result(pmysql);
1022 if (pres1 != NULL)
1023 {
1024 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1025 {
1026 /* check dll */
1027 sprintf(pszQuery, "SELECT name FROM dll WHERE refcode = %s", row1[1]);
1028 rc = mysql_query(pmysql, pszQuery);
1029 CheckFKError("function/dll", "Foreign key 'dll' not found in the dll table");
1030
1031 /* check state */
1032 sprintf(pszQuery, "SELECT name FROM state WHERE refcode = %s", row1[2]);
1033 rc = mysql_query(pmysql, pszQuery);
1034 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1035
1036 /* check apigroup */
1037 if (row1[3] != NULL)
1038 {
1039 sprintf(pszQuery, "SELECT name FROM apigroup WHERE refcode = %s", row1[3]);
1040 rc = mysql_query(pmysql, pszQuery);
1041 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1042 }
1043 }
1044 mysql_free_result(pres1);
1045 }
1046 }
1047 else
1048 ulRc += logDbError(pszError, pszQuery);
1049
1050 /* foreign keys in apigroup */
1051 strcpy(pszQuery, "SELECT refcode, dll FROM apigroup");
1052 rc = mysql_query(pmysql, pszQuery);
1053 if (rc >= 0)
1054 {
1055 pres1 = mysql_store_result(pmysql);
1056 if (pres1 != NULL)
1057 {
1058 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1059 {
1060 /* check dll */
1061 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1062 rc = mysql_query(pmysql, pszQuery);
1063 CheckFKError("apigroup/dll", "Foreign key 'dll' not found in the dll table");
1064 }
1065 mysql_free_result(pres1);
1066 }
1067 }
1068 else
1069 ulRc += logDbError(pszError, pszQuery);
1070
1071 /* foreign keys in fnauthor */
1072 strcpy(pszQuery, "SELECT function, author FROM fnauthor");
1073 rc = mysql_query(pmysql, pszQuery);
1074 if (rc >= 0)
1075 {
1076 pres1 = mysql_store_result(pmysql);
1077 if (pres1 != NULL)
1078 {
1079 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1080 {
1081 /* check function */
1082 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1083 rc = mysql_query(pmysql, pszQuery);
1084 CheckFKError("fnauthor/function", "Foreign key 'function' not found in the function table");
1085
1086 /* check author */
1087 sprintf(pszQuery, "SELECT refcode FROM author WHERE refcode = %s", row1[1]);
1088 rc = mysql_query(pmysql, pszQuery);
1089 CheckFKError("fnauthor/author", "Foreign key 'author' not found in the author table");
1090 }
1091 mysql_free_result(pres1);
1092 }
1093 }
1094 else
1095 ulRc += logDbError(pszError, pszQuery);
1096
1097 /* foreign keys in historydll table */
1098 strcpy(pszQuery, "SELECT date, dll, state FROM historydll");
1099 rc = mysql_query(pmysql, pszQuery);
1100 if (rc >= 0)
1101 {
1102 pres1 = mysql_store_result(pmysql);
1103 if (pres1 != NULL)
1104 {
1105 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1106 {
1107 /* check dll */
1108 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1109 rc = mysql_query(pmysql, pszQuery);
1110 CheckFKError("historydll/dll", "Foreign key 'dll' not found in the dll table");
1111
1112 /* check state */
1113 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1114 rc = mysql_query(pmysql, pszQuery);
1115 CheckFKError("historydll/state", "Foreign key 'state' not found in the state table");
1116 }
1117 mysql_free_result(pres1);
1118 }
1119 }
1120 else
1121 ulRc += logDbError(pszError, pszQuery);
1122
1123 /* foreign keys in historyapigroup table */
1124 strcpy(pszQuery, "SELECT date, apigroup, state FROM historyapigroup");
1125 rc = mysql_query(pmysql, pszQuery);
1126 if (rc >= 0)
1127 {
1128 pres1 = mysql_store_result(pmysql);
1129 if (pres1 != NULL)
1130 {
1131 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1132 {
1133 /* check dll */
1134 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1135 rc = mysql_query(pmysql, pszQuery);
1136 CheckFKError("historyapigroup/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1137
1138 /* check state */
1139 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1140 rc = mysql_query(pmysql, pszQuery);
1141 CheckFKError("historyapigroup/state", "Foreign key 'state' not found in the state table");
1142 }
1143 mysql_free_result(pres1);
1144 }
1145 }
1146 else
1147 ulRc += logDbError(pszError, pszQuery);
1148
1149 /* foreign keys in historydlltotal table */
1150 strcpy(pszQuery, "SELECT date, dll FROM historydlltotal");
1151 rc = mysql_query(pmysql, pszQuery);
1152 if (rc >= 0)
1153 {
1154 pres1 = mysql_store_result(pmysql);
1155 if (pres1 != NULL)
1156 {
1157 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1158 {
1159 /* check dll */
1160 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1161 rc = mysql_query(pmysql, pszQuery);
1162 CheckFKError("historydlltotal/dll", "Foreign key 'dll' not found in the dll table");
1163 }
1164 mysql_free_result(pres1);
1165 }
1166 }
1167 else
1168 ulRc += logDbError(pszError, pszQuery);
1169
1170 /* foreign keys in historyapigroup table */
1171 strcpy(pszQuery, "SELECT date, apigroup FROM historyapigrouptotal");
1172 rc = mysql_query(pmysql, pszQuery);
1173 if (rc >= 0)
1174 {
1175 pres1 = mysql_store_result(pmysql);
1176 if (pres1 != NULL)
1177 {
1178 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1179 {
1180 /* check dll */
1181 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1182 rc = mysql_query(pmysql, pszQuery);
1183 CheckFKError("historyapigrouptotal/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1184 }
1185 mysql_free_result(pres1);
1186 }
1187 }
1188 else
1189 ulRc += logDbError(pszError, pszQuery);
1190
1191 /* foreign keys in parameter table */
1192 strcpy(pszQuery, "SELECT sequencenbr, function FROM parameter");
1193 rc = mysql_query(pmysql, pszQuery);
1194 if (rc >= 0)
1195 {
1196 pres1 = mysql_store_result(pmysql);
1197 if (pres1 != NULL)
1198 {
1199 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1200 {
1201 /* check function */
1202 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1203 rc = mysql_query(pmysql, pszQuery);
1204 CheckFKError("parameter/function", "Foreign key 'function' not found in the function table");
1205 }
1206 mysql_free_result(pres1);
1207 }
1208 }
1209 else
1210 ulRc += logDbError(pszError, pszQuery);
1211
1212 /* Author table is special, since you should be able to interchangably reference an
1213 * author by any of the following tables:
1214 * name
1215 * initials
1216 * alias
1217 * email
1218 */
1219 strcpy(pszQuery, "SELECT name, initials, alias, email FROM author");
1220 rc = mysql_query(pmysql, pszQuery);
1221 if (rc >= 0)
1222 {
1223 pres1 = mysql_store_result(pmysql);
1224 if (pres1 != NULL)
1225 {
1226 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1227 {
1228 /* check name */
1229 sprintf(pszQuery, "SELECT name FROM author WHERE "
1230 "initials = '%s' OR alias = '%s' OR email = '%s'",
1231 row1[0], row1[0], row1[0]);
1232 ulRc += CheckAuthorError(pszError, "name", row1[0], pszQuery);
1233
1234 /* check initials */
1235 sprintf(pszQuery, "SELECT name FROM author WHERE "
1236 "alias = '%s' OR email = '%s'",
1237 row1[1], row1[1]);
1238 ulRc += CheckAuthorError(pszError, "initials", row1[1], pszQuery);
1239
1240 /* alias */
1241 if (row1[2] != NULL)
1242 {
1243 sprintf(pszQuery, "SELECT name FROM author WHERE "
1244 "email = '%s'",
1245 row1[2]);
1246 ulRc += CheckAuthorError(pszError, "alias", row1[2], pszQuery);
1247 }
1248 }
1249 mysql_free_result(pres1);
1250 }
1251 }
1252 else
1253 ulRc += logDbError(pszError, pszQuery);
1254
1255 return ulRc;
1256}
1257
1258
1259/**
1260 * Checks for duplicate key and sql error for a given author key in the author table... (arg!)
1261 * @returns Number of errors.
1262 * @param pszError Reference to error buffer pointer.
1263 * @param pszFieldName Key field name; used for logging.
1264 * @param pszFieldValue Key value; used for logging
1265 * @param pszQuery Query which is to be exectued to test for duplicate key.
1266 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1267 */
1268static unsigned long CheckAuthorError(char * &pszError, const char *pszFieldName, const char *pszFieldValue, const char *pszQuery)
1269{
1270 MYSQL_ROW row;
1271 MYSQL_RES *pres;
1272 unsigned long ulRc = 0;
1273 int rc;
1274
1275 rc = mysql_query(pmysql, pszQuery);
1276 pres = mysql_store_result(pmysql);
1277 if (rc < 0 || (pres != NULL && mysql_num_rows(pres) != 0))
1278 { /* some kind of error has occurred */
1279 if (pszError[1] == '\xFE')
1280 {
1281 strcat(pszError, "\n\t");
1282 pszError += 2;
1283 }
1284
1285 if (rc < 0) /* sql error or 'duplicate key' */
1286 {
1287 sprintf(pszError, "author/%s: select failed - %s (sql=%s)",
1288 pszFieldName, dbGetLastErrorDesc(), pszQuery);
1289 }
1290 else
1291 { /* 'duplicate key' - print duplicates */
1292 sprintf(pszError, "author/%s: 'duplicate key', %s='%s': ",
1293 pszFieldName, pszFieldValue, pszFieldName);
1294
1295 while ((row = mysql_fetch_row(pres)) != NULL)
1296 {
1297 pszError += strlen(pszError);
1298 sprintf(pszError, "'%s' ", row[0]);
1299 }
1300 }
1301
1302 pszError += strlen(pszError);
1303 pszError[1] = '\xFE';
1304 ulRc = 1;
1305 }
1306 if (pres != NULL)
1307 mysql_free_result(pres);
1308
1309 return ulRc;
1310}
1311
1312
1313/**
1314 * Writes db error (rc<0) to the log buffer.
1315 * @returns Number of signals.
1316 * @param pszError Reference to the error buffer pointer.
1317 * @param pszQuery Pointer to query which was executed.
1318 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1319 */
1320static unsigned long logDbError(char * &pszError, const char *pszQuery)
1321{
1322 if (pszError[1] == '\xFE')
1323 {
1324 strcat(pszError, "\n\t");
1325 pszError += 2;
1326 }
1327 sprintf(pszError, "select failed: %s - (sql=%s)", dbGetLastErrorDesc(), pszQuery);
1328
1329 pszError += strlen(pszError);
1330 pszError[1] = '\xFE';
1331
1332 return 1;
1333}
1334
1335
1336/**
1337 * Executes a give query and returns a result identifier/pointer.
1338 * @returns Query result identifier/pointer. NULL on error.
1339 * @param pszQuery Pointer to query.
1340 * @remark Used by and designed for kHtmlPC.
1341 */
1342void * _System dbExecuteQuery(const char *pszQuery)
1343{
1344 assert(pmysql != NULL);
1345 if (mysql_query(pmysql, pszQuery) >= 0)
1346 return mysql_store_result(pmysql);
1347
1348 return NULL;
1349}
1350
1351
1352/**
1353 * Asks for the number of rows in the result.
1354 * @returns Number of rows in the result. -1 on error.
1355 * @param pres Query result identifier/pointer.
1356 * @remark Used by and designed for kHtmlPC.
1357 */
1358signed long _System dbQueryResultRows(void *pres)
1359{
1360 if (pres == NULL)
1361 return -1;
1362 return mysql_num_rows((MYSQL_RES*)pres);
1363}
1364
1365
1366/**
1367 * Frees the storage allocated by the given result.
1368 * @returns Success indicator, TRUE/FALSE.
1369 * @param pres Query result identifier/pointer.
1370 * @remark Used by and designed for kHtmlPC.
1371 */
1372BOOL _System dbFreeResult(void *pres)
1373{
1374 if (pres != NULL)
1375 mysql_free_result((MYSQL_RES*)pres);
1376 else
1377 return FALSE;
1378 return TRUE;
1379}
1380
1381
1382/**
1383 * Fetch data from a result. Returns the data by calling the given callback function.
1384 * @returns Success indicator, TRUE/FALSE.
1385 * @param pres Query result identifier/pointer.
1386 * @param dbFetchCallBack Callback-function.
1387 * @param pvUser User parameter which is passed onto dbFetchCallBack.
1388 * @remark Used by and designed for kHtmlPC.
1389 */
1390BOOL _System dbFetch(void *pres, DBCALLBACKFETCH dbFetchCallBack, void *pvUser)
1391{
1392 BOOL fRc = FALSE;
1393 MYSQL_ROW row = mysql_fetch_row((MYSQL_RES*)pres);
1394
1395 if (row)
1396 {
1397 MYSQL_FIELD *pField;
1398 int i = 0;
1399 mysql_field_seek((MYSQL_RES*)pres, 0);
1400
1401 while ((pField = mysql_fetch_field((MYSQL_RES*)pres)) != NULL)
1402 if (dbFetchCallBack(row[i++], pField->name, pvUser) != 0)
1403 return FALSE;
1404
1405 fRc = TRUE;
1406 }
1407
1408 return fRc;
1409}
1410
1411
1412/**
1413 * Converts an ISO date to days after Christ, year 0.
1414 * @returns days. -1 on error;
1415 * @param pszDate ISO Date.
1416 */
1417signed long _System dbDateToDaysAfterChrist(const char *pszDate)
1418{
1419 signed long lRet = -1;
1420 char szQuery[128];
1421
1422 sprintf(&szQuery[0], "SELECT to_days('%s')", pszDate);
1423 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1424 {
1425 MYSQL_ROW row;
1426 MYSQL_RES *pres = mysql_use_result(pmysql);
1427 row = mysql_fetch_row(pres);
1428 if (row != NULL)
1429 {
1430 lRet = atol(row[0]);
1431 do { row = mysql_fetch_row(pres); } while (row != NULL);
1432 }
1433 }
1434
1435 return lRet;
1436}
1437
1438
1439/**
1440 * Converts days after Christ (year 0) to ISO date.
1441 * @returns Success indicator. TRUE/FALSE;
1442 * @param lDays Days after Christ (year 0).
1443 * @param pszDate ISO Date. Result.
1444 */
1445BOOL _System dbDaysAfterChristToDate(signed long lDays, char *pszDate)
1446{
1447 BOOL fRet = FALSE;
1448 char szQuery[128];
1449
1450 if (lDays < 0)
1451 return FALSE;
1452
1453 sprintf(&szQuery[0], "SELECT from_days(%ld)", lDays);
1454 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1455 {
1456 MYSQL_ROW row;
1457 MYSQL_RES *pres = mysql_use_result(pmysql);
1458 row = mysql_fetch_row(pres);
1459 if (row != NULL)
1460 {
1461 fRet = strlen(row[0]) == (4+1+2+1+2) && row[0][4] == '-' && row[0][7] == '-'
1462 && strcmp(row[0], "0000-00-00") != 0;
1463 if (fRet)
1464 strcpy(pszDate, row[0]);
1465 do { row = mysql_fetch_row(pres); } while (row != NULL);
1466 }
1467 }
1468
1469 return fRet;
1470}
1471
1472
1473/**
1474 * Display all functions for, the given dll, that is not updated.
1475 * @returns TRUE / FALSE.
1476 * @param lDll Dll reference number.
1477 * @param dbFetchCall Callback function which will be called once for each
1478 * field for all the functions not updated.
1479 * pvUser is NULL, pszValue field value, pszFieldName the field name.
1480 */
1481BOOL _System dbGetNotUpdatedFunction(signed long lDll, DBCALLBACKFETCH dbFetchCallBack)
1482{
1483 BOOL fRet = FALSE;
1484 void *pres;
1485 char szQuery[256];
1486
1487 /* not updated names */
1488 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1489 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1490 " LEFT JOIN dll d ON f2.dll = d.refcode "
1491 "WHERE f1.dll = %ld AND f1.updated = 0",
1492 lDll);
1493 pres = dbExecuteQuery(szQuery);
1494 if (pres != NULL)
1495 {
1496 BOOL f;
1497 do
1498 {
1499 f = dbFetch(pres, dbFetchCallBack, NULL);
1500 } while (f);
1501 dbFreeResult(pres);
1502 fRet = TRUE;
1503 }
1504
1505 /* warn about updated > 1 too */
1506 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1507 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1508 " LEFT JOIN dll d ON f2.dll = d.refcode "
1509 "WHERE f1.dll = %ld AND f1.updated > 1",
1510 lDll);
1511 pres = dbExecuteQuery(szQuery);
1512 if (pres != NULL)
1513 {
1514 BOOL f;
1515 do
1516 {
1517 f = dbFetch(pres, dbFetchCallBack, NULL);
1518 } while (f);
1519 dbFreeResult(pres);
1520 fRet = TRUE;
1521 }
1522
1523 strcpy(&szQuery[0], "UPDATE function SET updated = 0");
1524 mysql_query(pmysql, &szQuery[0]);
1525
1526 return fRet;
1527}
1528
1529
1530/**
1531 * Counts the function for the given DLL which has been updated.
1532 * @returns -1 on error, number of updated function on success.
1533 * @param lDll Dll reference number.
1534 */
1535signed long _System dbGetNumberOfUpdatedFunction(signed long lDll)
1536{
1537 int rc;
1538 char szQuery[128];
1539 MYSQL_RES * pres;
1540
1541 sprintf(&szQuery[0], "SELECT count(*) FROM function WHERE dll = (%ld) AND updated > 0\n", lDll);
1542 rc = mysql_query(pmysql, &szQuery[0]);
1543 pres = mysql_store_result(pmysql);
1544 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
1545 rc = (int)getvalue(0, mysql_fetch_row(pres));
1546 else
1547 rc = -1;
1548 mysql_free_result(pres);
1549 return (signed long)rc;
1550}
1551
1552
1553#ifndef DLL
1554/**
1555 * Signal handler.
1556 * Ensures that the database connection is closed at termination.
1557 * @param sig Signal number.
1558 */
1559void dbHandler(int sig)
1560{
1561 if (pmysql != NULL)
1562 {
1563 fprintf(stderr, "\n\t!disconnecting from database!\n");
1564 dbDisconnect();
1565 }
1566
1567 flushall();
1568 switch (sig)
1569 {
1570 case SIGBREAK:
1571 printf("\nSIGBREAK\n");
1572 exit(-1);
1573 break;
1574 case SIGINT:
1575 printf("\nSIGINT\n");
1576 exit(-1);
1577 break;
1578 case SIGTERM:
1579 printf("\nSIGTERM\n");
1580 exit(-1);
1581 break;
1582 case SIGSEGV:
1583 raise(sig);
1584 break;
1585 case SIGILL:
1586 printf("\nSIGILL\n");
1587 exit(-1);
1588 break;
1589 }
1590}
1591
1592
1593#else
1594/*******/
1595/* DLL */
1596/*******/
1597/* prototypes used in the _DLL_InitTerm function */
1598extern "C"
1599{
1600 int _CRT_init(void);
1601 void _CRT_term(void);
1602 void __ctordtorInit( void );
1603 void __ctordtorTerm( void );
1604 unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag);
1605}
1606
1607
1608/**
1609 * Dll InitTerm function.
1610 * @returns 0 on success.
1611 * 1 on error.
1612 * @param hModule
1613 * @param ulFlags
1614 * @remark We'll ensure that the database connection is terminated as we terminate.
1615 */
1616unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag)
1617{
1618 /*-------------------------------------------------------------------------*/
1619 /* If ulFlag is zero then the DLL is being loaded so initialization should */
1620 /* be performed. If ulFlag is 1 then the DLL is being freed so */
1621 /* termination should be performed. */
1622 /*-------------------------------------------------------------------------*/
1623
1624 switch (ulFlag)
1625 {
1626 case 0:
1627 if (_CRT_init() == -1)
1628 return 0;
1629 __ctordtorInit();
1630 break;
1631
1632 case 1:
1633 /* ensure that db connection is terminated */
1634 if (pmysql != NULL)
1635 {
1636 fprintf(stderr, "\n\t!disconnecting from database!\n");
1637 dbDisconnect();
1638 }
1639 __ctordtorTerm();
1640 break;
1641
1642 default:
1643 return 0;
1644 }
1645 hModule = hModule;
1646 return 1;
1647}
1648
1649/*****************************************************************/
1650/* -why is this terminate function referenced but not defined??? */
1651/* and where is it referenced??? */
1652/* -Probably an export missing from the libraries. */
1653/*****************************************************************/
1654void terminate(void)
1655{
1656 DosPutMessage(0, sizeof("terminate")-1, "terminate");
1657 exit(-1);
1658}
1659
1660/****************************************/
1661/* EMX run-time trouble */
1662/* _environ is missing when using -Zomf */
1663/****************************************/
1664char **_environ = environ;
1665
1666#endif
Note: See TracBrowser for help on using the repository browser.