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

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

Optimizations and a couple of fixes.

File size: 56.5 KB
Line 
1/* $Id: db.cpp,v 1.9 2000-02-14 13:49:13 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[256];
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;
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 (",
550 lDll, pszFunctionName);
551 for (i = 0; i < cFnsThisDll; i++)
552 {
553 if (i != 0) strcat(&szQuery[0], " OR");
554 sprintf(&szQuery[strlen(szQuery)], " refcode = %ld", pFnFindBuf->alRefCode[i]);
555 }
556 strcat(&szQuery[0], ") AND aliasfn <> (-2)");
557
558 rc = mysql_query5(pmysql, &szQuery[0]);
559 if (rc >= 0 && cFnsAliasesAndThisDll < pFnFindBuf->cFns)
560 {
561 /*
562 * 6) Update all functions from (3) and (4) to alias the first function from 1.
563 */
564 sprintf(&szQuery[0], "UPDATE function SET aliasfn = (%ld) "
565 "WHERE aliasfn = (-1) AND refcode IN (",
566 pFnFindBuf->alRefCode[0]);
567 for (i = cFnsAliasesAndThisDll; i < pFnFindBuf->cFns; i++)
568 sprintf(&szQuery[strlen(&szQuery[0])],
569 i > 0 ? ", %ld" : "%ld", pFnFindBuf->alRefCode[i]);
570 strcat(&szQuery[0], ")");
571 rc = mysql_query6(pmysql, &szQuery[0]);
572 } /* query 5 */
573 }
574 } /* query 4 */
575 }
576 } /* query 3 */
577 }
578 } /* query 2 */
579 }
580 } /* query 1 */
581 else
582 rc = -1;
583 }
584
585 return rc >= 0;
586}
587
588
589/**
590 * Finds the refcode for an author, if the author exists.
591 * @returns Author 'refcode'.
592 * @param pszAuthor String which holds the identifier of an author.
593 * This doesn't have to be the name. Initials, alias and email
594 * is also searched.
595 */
596signed long _System dbFindAuthor(const char *pszAuthor)
597{
598 signed long refcode = -1;
599 MYSQL_RES *pres;
600 char szQuery[256];
601
602 sprintf(&szQuery[0],
603 "SELECT refcode FROM author "
604 "WHERE name = '%s' OR "
605 " initials = '%s' OR "
606 " alias = '%s' OR "
607 " email = '%s'",
608 pszAuthor, pszAuthor, pszAuthor, pszAuthor);
609 if (mysql_query(pmysql, &szQuery[0]) >= 0)
610 {
611 pres = mysql_store_result(pmysql);
612 if (pres != NULL)
613 {
614 MYSQL_ROW parow;
615
616 /* integrety check */
617 if (mysql_num_rows(pres) > 1)
618 fprintf(stderr, "Integrety: author '%s' is not unique!\n", pszAuthor);
619 parow = mysql_fetch_row(pres);
620 if (parow != NULL)
621 refcode = getvalue(0, parow);
622
623 mysql_free_result(pres);
624 }
625 }
626
627 return refcode;
628}
629
630
631/**
632 * Gets the state of a function.
633 * @returns state code. On error -1.
634 * @param lRefCode Function refcode.
635 */
636signed long _System dbGetFunctionState(signed long lRefCode)
637{
638 signed long lState = -1;
639 MYSQL_RES *pres;
640 char szQuery[128];
641
642 sprintf(&szQuery[0], "SELECT state FROM function WHERE refcode = %ld", lRefCode);
643 if (mysql_query(pmysql, &szQuery[0]) >= 0)
644 {
645 pres = mysql_store_result(pmysql);
646 if (pres != NULL)
647 {
648 MYSQL_ROW parow = mysql_fetch_row(pres);
649 if (parow != NULL)
650 lState = getvalue(0, parow);
651 mysql_free_result(pres);
652 }
653 }
654
655 return lState;
656}
657
658#if 1
659/*
660 * Stubs used while optimizing sqls.
661 */
662int mysql_queryu1(MYSQL *mysql, const char *q)
663{ return mysql_query(mysql, q); }
664int mysql_queryu2(MYSQL *mysql, const char *q)
665{ return mysql_query(mysql, q); }
666int mysql_queryu3(MYSQL *mysql, const char *q)
667{ return mysql_query(mysql, q); }
668int mysql_queryu4(MYSQL *mysql, const char *q)
669{ return mysql_query(mysql, q); }
670int mysql_queryu5(MYSQL *mysql, const char *q)
671{ return mysql_query(mysql, q); }
672int mysql_queryu6(MYSQL *mysql, const char *q)
673{ return mysql_query(mysql, q); }
674int mysql_queryu7(MYSQL *mysql, const char *q)
675{ return mysql_query(mysql, q); }
676int mysql_queryu8(MYSQL *mysql, const char *q)
677{ return mysql_query(mysql, q); }
678#else
679#define mysql_queryu1 mysql_query
680#define mysql_queryu2 mysql_query
681#define mysql_queryu3 mysql_query
682#define mysql_queryu4 mysql_query
683#define mysql_queryu5 mysql_query
684#define mysql_queryu6 mysql_query
685#define mysql_queryu7 mysql_query
686#define mysql_queryu8 mysql_query
687#endif
688
689/**
690 * Updates function information.
691 * @returns number of errors.
692 * @param pFnDesc Function description struct.
693 * @param lDll Dll which we are working at.
694 * @param pszError Buffer for error messages
695 * @result on error(s) pszError will hold information about the error(s).
696 */
697unsigned long _System dbUpdateFunction(PFNDESC pFnDesc, signed long lDll, char *pszError)
698{
699 MYSQL_RES * pres;
700 MYSQL_ROW row;
701 char szQuery[512];
702 char * pszQuery = &szQuery[0];
703 long lCurrentState;
704 int i,k,rc;
705 unsigned long ulRc = 0;
706
707 for (k = 0; k < pFnDesc->cRefCodes; k++)
708 {
709 BOOL f = FALSE;
710
711 /*
712 * Set updated flag
713 */
714 sprintf(pszQuery, "UPDATE function SET updated = updated + 1 WHERE refcode = %ld",
715 pFnDesc->alRefCode[k]);
716 rc = mysql_queryu1(pmysql, &szQuery[0]);
717
718
719 /*
720 * Get current status
721 */
722 lCurrentState = dbGetFunctionState(pFnDesc->alRefCode[k]);
723 if (lCurrentState == -1)
724 {
725 strcpy(pszError, dbGetLastErrorDesc());
726 return 1;
727 }
728
729
730 /*
731 * Update function table first
732 */
733 strcpy(pszQuery, "UPDATE function SET ");
734 pszQuery += strlen(pszQuery);
735 if (pFnDesc->lStatus != 99 || lCurrentState == 0)
736 {
737 sprintf(pszQuery, "state = %ld ", pFnDesc->lStatus);
738 f = TRUE;
739 }
740 pszQuery += strlen(pszQuery);
741
742 if (pFnDesc->pszReturnType != NULL)
743 {
744 if (f) strcat(pszQuery, ", ");
745 sprintf(pszQuery + strlen(pszQuery), "return = '%s' ", pFnDesc->pszReturnType);
746 pszQuery += strlen(pszQuery);
747 f = TRUE;
748 }
749
750 if (f)
751 {
752 sprintf(pszQuery + strlen(pszQuery), "WHERE refcode = %ld", pFnDesc->alRefCode[k]);
753 rc = mysql_queryu2(pmysql, &szQuery[0]);
754 if (rc < 0)
755 {
756 sprintf(pszError, "Updating functiontable failed with error: %s - (sql=%s) ",
757 dbGetLastErrorDesc(), &szQuery[0]);
758 pszError += strlen(pszError) - 1;
759 ulRc++;
760 }
761 }
762
763
764 /*
765 * Parameters
766 */
767 pszQuery = &szQuery[0];
768 sprintf(pszQuery, "SELECT count(*) FROM parameter WHERE function = %ld", pFnDesc->alRefCode[k]);
769 rc = mysql_queryu3(pmysql, pszQuery);
770 if (rc >= 0)
771 {
772 pres = mysql_store_result(pmysql);
773 if (pres != NULL)
774 row = mysql_fetch_row(pres);
775 if (pres != NULL && row != NULL && mysql_num_rows(pres) == 1)
776 {
777 if (atol(row[0]) == pFnDesc->cParams)
778 { /* update parameters */
779 for (i = 0; i < pFnDesc->cParams; i++)
780 {
781 sprintf(pszQuery, "UPDATE parameter SET type = '%s', name = '%s' "
782 "WHERE function = (%ld) AND sequencenbr == (%ld)",
783 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
784 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : "",
785 pFnDesc->alRefCode[k], i
786 );
787 rc = mysql_queryu4(pmysql, pszQuery);
788 if (rc < 0)
789 {
790 if (*pszError == ' ')
791 strcpy(pszError++, "\n\t");
792 sprintf(pszError, "Updateing parameter %i failed with error: %s - (sql=%s) ",
793 i, dbGetLastErrorDesc(), pszQuery);
794 pszError += strlen(pszError) - 1;
795 ulRc++;
796 }
797 }
798 }
799 else
800 {
801 if (atol(row[0]) != 0)
802 { /* delete old parameters */
803 sprintf(pszQuery, "DELETE FROM parameter WHERE function = %ld", pFnDesc->alRefCode[k]);
804 rc = mysql_queryu5(pmysql, pszQuery);
805 if (rc < 0)
806 {
807 if (*pszError == ' ')
808 strcpy(pszError++, "\n\t");
809 sprintf(pszError, "Deleting old parameters failed with error: %s - (sql=%s) ",
810 dbGetLastErrorDesc(), pszQuery);
811 pszError += strlen(pszError) - 1;
812 ulRc++;
813 }
814 }
815
816 /* insert parameters */
817 for (i = 0; i < pFnDesc->cParams; i++)
818 {
819 sprintf(pszQuery, "INSERT INTO parameter(function, sequencenbr, type, name) "
820 "VALUES (%ld, %d, '%s', '%s')",
821 pFnDesc->alRefCode[k], i,
822 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
823 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : ""
824 );
825 rc = mysql_queryu6(pmysql, pszQuery);
826 if (rc < 0)
827 {
828 if (*pszError == ' ')
829 strcpy(pszError++, "\n\t");
830 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
831 i, dbGetLastErrorDesc(), pszQuery);
832 pszError += strlen(pszError) - 1;
833 ulRc++;
834 }
835 }
836 }
837 }
838 else
839 {
840 if (*pszError == ' ')
841 strcpy(pszError++, "\n\t");
842 sprintf(pszError, "failed to store result or to fetch a row , error: %s - (sql=%s) ",
843 dbGetLastErrorDesc(), pszQuery);
844 pszError += strlen(pszError) - 1;
845 ulRc++;
846 }
847 }
848 else
849 {
850 if (*pszError == ' ')
851 strcpy(pszError++, "\n\t");
852 sprintf(pszError, "Failed querying number of parameters, error: %s - (sql=%s) ",
853 dbGetLastErrorDesc(), pszQuery);
854 pszError += strlen(pszError) - 1;
855 ulRc++;
856 }
857
858
859 /*
860 * Authors
861 */
862 sprintf(pszQuery, "DELETE FROM fnauthor WHERE function = %ld", pFnDesc->alRefCode[k]);
863 rc = mysql_queryu7(pmysql, pszQuery);
864 if (rc < 0)
865 {
866 if (*pszError == ' ')
867 strcpy(pszError++, "\n\t");
868 sprintf(pszError, "Deleting old authors failed with error: %s - (sql=%s) ",
869 dbGetLastErrorDesc(), pszQuery);
870 pszError += strlen(pszError) - 1;
871 ulRc++;
872 }
873
874 for (i = 0; i < pFnDesc->cAuthors; i++)
875 {
876 if (pFnDesc->alAuthorRefCode[i] == -1)
877 continue;
878 sprintf(pszQuery, "INSERT INTO fnauthor(author, function) "
879 "VALUES (%ld, %ld)",
880 pFnDesc->alAuthorRefCode[i], pFnDesc->alRefCode[k]);
881 rc = mysql_queryu8(pmysql, pszQuery);
882 if (rc < 0)
883 {
884 if (*pszError == ' ')
885 strcpy(pszError++, "\n\t");
886 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
887 i, dbGetLastErrorDesc(), pszQuery);
888 pszError += strlen(pszError) - 1;
889 ulRc++;
890 }
891 }
892 } /* for */
893
894 lDll = lDll;
895 return ulRc;
896}
897
898
899/**
900 * Updates the history tables.
901 * @returns Number of signals/errors.
902 * @param pszError Pointer to buffer which will hold the error messages.
903 * @remark This should be called whenever updates have been completed.
904 */
905unsigned long _System dbCreateHistory(char *pszError)
906{
907 unsigned long ulRc = 0;
908 MYSQL_RES *pres;
909 MYSQL_ROW row;
910 char szQuery[256];
911 char *pszQuery = &szQuery[0];
912 int rc;
913 char szCurDt[20] = {0}; /*yyyy-mm-dd\0*/
914
915 mysql_refresh(pmysql, REFRESH_TABLES);
916
917 /* get currentdate - just in case the date changes between the delete and the update is completed. */
918 strcpy(pszQuery, "SELECT CURDATE()");
919 rc = mysql_query(pmysql, pszQuery);
920 pres = mysql_use_result(pmysql);
921 if (rc >= 0 && pres != NULL)
922 {
923 row = mysql_fetch_row(pres);
924 if (row != NULL && mysql_num_rows(pres) == 1)
925 {
926 strcpy(&szCurDt[0], row[0]);
927 while (mysql_fetch_row(pres) != NULL)
928 pres=pres;
929
930 /* delete - all rows on this date in the history tables */
931 sprintf(pszQuery, "DELETE FROM historydll WHERE date = '%s'", &szCurDt[0]);
932 rc = mysql_query(pmysql, pszQuery);
933 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
934
935 sprintf(pszQuery, "DELETE FROM historyapigroup WHERE date = '%s'", &szCurDt[0]);
936 rc = mysql_query(pmysql, pszQuery);
937 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
938
939 sprintf(pszQuery, "DELETE FROM historydlltotal WHERE date = '%s'", &szCurDt[0]);
940 rc = mysql_query(pmysql, pszQuery);
941 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
942
943 sprintf(pszQuery, "DELETE FROM historyapigrouptotal WHERE date = '%s'", &szCurDt[0]);
944 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
945
946 /* insert new stats */
947 sprintf(pszQuery, "INSERT INTO historydll(dll, state, date, count) "
948 "SELECT dll, state, '%s', count(*) FROM function GROUP BY dll, state",
949 &szCurDt[0]);
950 rc = mysql_query(pmysql, pszQuery);
951 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
952
953 sprintf(pszQuery, "INSERT INTO historyapigroup(apigroup, state, date, count) "
954 "SELECT dll, state, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
955 "GROUP BY apigroup, state",
956 &szCurDt[0]);
957 rc = mysql_query(pmysql, pszQuery);
958 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
959
960 /* inserting new totals */
961 sprintf(pszQuery, "INSERT INTO historydlltotal(dll, date, totalcount) "
962 "SELECT dll, '%s', count(*) FROM function GROUP BY dll",
963 &szCurDt[0]);
964 rc = mysql_query(pmysql, pszQuery);
965 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
966
967 sprintf(pszQuery, "INSERT INTO historyapigrouptotal(apigroup, date, totalcount) "
968 "SELECT apigroup, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
969 "GROUP BY apigroup",
970 &szCurDt[0]);
971 rc = mysql_query(pmysql, pszQuery);
972 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
973 }
974 else
975 {
976 sprintf(pszError, "error getting current date (row == NULL): %s - (sql=%s) ",
977 dbGetLastErrorDesc(), pszQuery);
978 ulRc++;
979 }
980 }
981 else
982 {
983 sprintf(pszError, "error getting current date: %s - (sql=%s) ",
984 dbGetLastErrorDesc(), pszQuery);
985 ulRc++;
986 }
987
988 mysql_refresh(pmysql, REFRESH_TABLES);
989
990 return ulRc;
991}
992
993
994/**
995 * Check that database integrety is ok. Verfies foreign keys.
996 * @returns numbers of errors.
997 * @param pszError Very large buffer which will hold error messges (if any).
998 * @sketch
999 * @remark current versions of mysql don't support 'SELECT ... WHERE id NOT IN(SELECT id FROM table)'
1000 */
1001unsigned long _System dbCheckIntegrity(char *pszError)
1002{
1003 char szQuery[384];
1004 char *pszQuery = &szQuery[0];
1005 MYSQL_RES *pres1;
1006 MYSQL_RES *pres2;
1007 MYSQL_ROW row1;
1008 int rc;
1009 unsigned long ulRc = 0;
1010
1011 mysql_refresh(pmysql, REFRESH_TABLES);
1012
1013 /* foreign keys in function table */
1014 strcpy(pszQuery, "SELECT refcode, dll, state, apigroup FROM function");
1015 rc = mysql_query(pmysql, pszQuery);
1016 if (rc >= 0)
1017 {
1018 pres1 = mysql_store_result(pmysql);
1019 if (pres1 != NULL)
1020 {
1021 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1022 {
1023 /* check dll */
1024 sprintf(pszQuery, "SELECT name FROM dll WHERE refcode = %s", row1[1]);
1025 rc = mysql_query(pmysql, pszQuery);
1026 CheckFKError("function/dll", "Foreign key 'dll' not found in the dll table");
1027
1028 /* check state */
1029 sprintf(pszQuery, "SELECT name FROM state WHERE refcode = %s", row1[2]);
1030 rc = mysql_query(pmysql, pszQuery);
1031 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1032
1033 /* check apigroup */
1034 if (row1[3] != NULL)
1035 {
1036 sprintf(pszQuery, "SELECT name FROM apigroup WHERE refcode = %s", row1[3]);
1037 rc = mysql_query(pmysql, pszQuery);
1038 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1039 }
1040 }
1041 mysql_free_result(pres1);
1042 }
1043 }
1044 else
1045 ulRc += logDbError(pszError, pszQuery);
1046
1047 /* foreign keys in apigroup */
1048 strcpy(pszQuery, "SELECT refcode, dll FROM apigroup");
1049 rc = mysql_query(pmysql, pszQuery);
1050 if (rc >= 0)
1051 {
1052 pres1 = mysql_store_result(pmysql);
1053 if (pres1 != NULL)
1054 {
1055 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1056 {
1057 /* check dll */
1058 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1059 rc = mysql_query(pmysql, pszQuery);
1060 CheckFKError("apigroup/dll", "Foreign key 'dll' not found in the dll table");
1061 }
1062 mysql_free_result(pres1);
1063 }
1064 }
1065 else
1066 ulRc += logDbError(pszError, pszQuery);
1067
1068 /* foreign keys in fnauthor */
1069 strcpy(pszQuery, "SELECT function, author FROM fnauthor");
1070 rc = mysql_query(pmysql, pszQuery);
1071 if (rc >= 0)
1072 {
1073 pres1 = mysql_store_result(pmysql);
1074 if (pres1 != NULL)
1075 {
1076 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1077 {
1078 /* check function */
1079 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1080 rc = mysql_query(pmysql, pszQuery);
1081 CheckFKError("fnauthor/function", "Foreign key 'function' not found in the function table");
1082
1083 /* check author */
1084 sprintf(pszQuery, "SELECT refcode FROM author WHERE refcode = %s", row1[1]);
1085 rc = mysql_query(pmysql, pszQuery);
1086 CheckFKError("fnauthor/author", "Foreign key 'author' not found in the author table");
1087 }
1088 mysql_free_result(pres1);
1089 }
1090 }
1091 else
1092 ulRc += logDbError(pszError, pszQuery);
1093
1094 /* foreign keys in historydll table */
1095 strcpy(pszQuery, "SELECT date, dll, state FROM historydll");
1096 rc = mysql_query(pmysql, pszQuery);
1097 if (rc >= 0)
1098 {
1099 pres1 = mysql_store_result(pmysql);
1100 if (pres1 != NULL)
1101 {
1102 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1103 {
1104 /* check dll */
1105 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1106 rc = mysql_query(pmysql, pszQuery);
1107 CheckFKError("historydll/dll", "Foreign key 'dll' not found in the dll table");
1108
1109 /* check state */
1110 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1111 rc = mysql_query(pmysql, pszQuery);
1112 CheckFKError("historydll/state", "Foreign key 'state' not found in the state table");
1113 }
1114 mysql_free_result(pres1);
1115 }
1116 }
1117 else
1118 ulRc += logDbError(pszError, pszQuery);
1119
1120 /* foreign keys in historyapigroup table */
1121 strcpy(pszQuery, "SELECT date, apigroup, state FROM historyapigroup");
1122 rc = mysql_query(pmysql, pszQuery);
1123 if (rc >= 0)
1124 {
1125 pres1 = mysql_store_result(pmysql);
1126 if (pres1 != NULL)
1127 {
1128 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1129 {
1130 /* check dll */
1131 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1132 rc = mysql_query(pmysql, pszQuery);
1133 CheckFKError("historyapigroup/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1134
1135 /* check state */
1136 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1137 rc = mysql_query(pmysql, pszQuery);
1138 CheckFKError("historyapigroup/state", "Foreign key 'state' not found in the state table");
1139 }
1140 mysql_free_result(pres1);
1141 }
1142 }
1143 else
1144 ulRc += logDbError(pszError, pszQuery);
1145
1146 /* foreign keys in historydlltotal table */
1147 strcpy(pszQuery, "SELECT date, dll FROM historydlltotal");
1148 rc = mysql_query(pmysql, pszQuery);
1149 if (rc >= 0)
1150 {
1151 pres1 = mysql_store_result(pmysql);
1152 if (pres1 != NULL)
1153 {
1154 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1155 {
1156 /* check dll */
1157 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1158 rc = mysql_query(pmysql, pszQuery);
1159 CheckFKError("historydlltotal/dll", "Foreign key 'dll' not found in the dll table");
1160 }
1161 mysql_free_result(pres1);
1162 }
1163 }
1164 else
1165 ulRc += logDbError(pszError, pszQuery);
1166
1167 /* foreign keys in historyapigroup table */
1168 strcpy(pszQuery, "SELECT date, apigroup FROM historyapigrouptotal");
1169 rc = mysql_query(pmysql, pszQuery);
1170 if (rc >= 0)
1171 {
1172 pres1 = mysql_store_result(pmysql);
1173 if (pres1 != NULL)
1174 {
1175 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1176 {
1177 /* check dll */
1178 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1179 rc = mysql_query(pmysql, pszQuery);
1180 CheckFKError("historyapigrouptotal/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1181 }
1182 mysql_free_result(pres1);
1183 }
1184 }
1185 else
1186 ulRc += logDbError(pszError, pszQuery);
1187
1188 /* foreign keys in parameter table */
1189 strcpy(pszQuery, "SELECT sequencenbr, function FROM parameter");
1190 rc = mysql_query(pmysql, pszQuery);
1191 if (rc >= 0)
1192 {
1193 pres1 = mysql_store_result(pmysql);
1194 if (pres1 != NULL)
1195 {
1196 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1197 {
1198 /* check function */
1199 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1200 rc = mysql_query(pmysql, pszQuery);
1201 CheckFKError("parameter/function", "Foreign key 'function' not found in the function table");
1202 }
1203 mysql_free_result(pres1);
1204 }
1205 }
1206 else
1207 ulRc += logDbError(pszError, pszQuery);
1208
1209 /* Author table is special, since you should be able to interchangably reference an
1210 * author by any of the following tables:
1211 * name
1212 * initials
1213 * alias
1214 * email
1215 */
1216 strcpy(pszQuery, "SELECT name, initials, alias, email FROM author");
1217 rc = mysql_query(pmysql, pszQuery);
1218 if (rc >= 0)
1219 {
1220 pres1 = mysql_store_result(pmysql);
1221 if (pres1 != NULL)
1222 {
1223 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1224 {
1225 /* check name */
1226 sprintf(pszQuery, "SELECT name FROM author WHERE "
1227 "initials = '%s' OR alias = '%s' OR email = '%s'",
1228 row1[0], row1[0], row1[0]);
1229 ulRc += CheckAuthorError(pszError, "name", row1[0], pszQuery);
1230
1231 /* check initials */
1232 sprintf(pszQuery, "SELECT name FROM author WHERE "
1233 "alias = '%s' OR email = '%s'",
1234 row1[1], row1[1]);
1235 ulRc += CheckAuthorError(pszError, "initials", row1[1], pszQuery);
1236
1237 /* alias */
1238 if (row1[2] != NULL)
1239 {
1240 sprintf(pszQuery, "SELECT name FROM author WHERE "
1241 "email = '%s'",
1242 row1[2]);
1243 ulRc += CheckAuthorError(pszError, "alias", row1[2], pszQuery);
1244 }
1245 }
1246 mysql_free_result(pres1);
1247 }
1248 }
1249 else
1250 ulRc += logDbError(pszError, pszQuery);
1251
1252 return ulRc;
1253}
1254
1255
1256/**
1257 * Checks for duplicate key and sql error for a given author key in the author table... (arg!)
1258 * @returns Number of errors.
1259 * @param pszError Reference to error buffer pointer.
1260 * @param pszFieldName Key field name; used for logging.
1261 * @param pszFieldValue Key value; used for logging
1262 * @param pszQuery Query which is to be exectued to test for duplicate key.
1263 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1264 */
1265static unsigned long CheckAuthorError(char * &pszError, const char *pszFieldName, const char *pszFieldValue, const char *pszQuery)
1266{
1267 MYSQL_ROW row;
1268 MYSQL_RES *pres;
1269 unsigned long ulRc = 0;
1270 int rc;
1271
1272 rc = mysql_query(pmysql, pszQuery);
1273 pres = mysql_store_result(pmysql);
1274 if (rc < 0 || (pres != NULL && mysql_num_rows(pres) != 0))
1275 { /* some kind of error has occurred */
1276 if (pszError[1] == '\xFE')
1277 {
1278 strcat(pszError, "\n\t");
1279 pszError += 2;
1280 }
1281
1282 if (rc < 0) /* sql error or 'duplicate key' */
1283 {
1284 sprintf(pszError, "author/%s: select failed - %s (sql=%s)",
1285 pszFieldName, dbGetLastErrorDesc(), pszQuery);
1286 }
1287 else
1288 { /* 'duplicate key' - print duplicates */
1289 sprintf(pszError, "author/%s: 'duplicate key', %s='%s': ",
1290 pszFieldName, pszFieldValue, pszFieldName);
1291
1292 while ((row = mysql_fetch_row(pres)) != NULL)
1293 {
1294 pszError += strlen(pszError);
1295 sprintf(pszError, "'%s' ", row[0]);
1296 }
1297 }
1298
1299 pszError += strlen(pszError);
1300 pszError[1] = '\xFE';
1301 ulRc = 1;
1302 }
1303 if (pres != NULL)
1304 mysql_free_result(pres);
1305
1306 return ulRc;
1307}
1308
1309
1310/**
1311 * Writes db error (rc<0) to the log buffer.
1312 * @returns Number of signals.
1313 * @param pszError Reference to the error buffer pointer.
1314 * @param pszQuery Pointer to query which was executed.
1315 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1316 */
1317static unsigned long logDbError(char * &pszError, const char *pszQuery)
1318{
1319 if (pszError[1] == '\xFE')
1320 {
1321 strcat(pszError, "\n\t");
1322 pszError += 2;
1323 }
1324 sprintf(pszError, "select failed: %s - (sql=%s)", dbGetLastErrorDesc(), pszQuery);
1325
1326 pszError += strlen(pszError);
1327 pszError[1] = '\xFE';
1328
1329 return 1;
1330}
1331
1332
1333/**
1334 * Executes a give query and returns a result identifier/pointer.
1335 * @returns Query result identifier/pointer. NULL on error.
1336 * @param pszQuery Pointer to query.
1337 * @remark Used by and designed for kHtmlPC.
1338 */
1339void * _System dbExecuteQuery(const char *pszQuery)
1340{
1341 assert(pmysql != NULL);
1342 if (mysql_query(pmysql, pszQuery) >= 0)
1343 return mysql_store_result(pmysql);
1344
1345 return NULL;
1346}
1347
1348
1349/**
1350 * Asks for the number of rows in the result.
1351 * @returns Number of rows in the result. -1 on error.
1352 * @param pres Query result identifier/pointer.
1353 * @remark Used by and designed for kHtmlPC.
1354 */
1355signed long _System dbQueryResultRows(void *pres)
1356{
1357 if (pres == NULL)
1358 return -1;
1359 return mysql_num_rows((MYSQL_RES*)pres);
1360}
1361
1362
1363/**
1364 * Frees the storage allocated by the given result.
1365 * @returns Success indicator, TRUE/FALSE.
1366 * @param pres Query result identifier/pointer.
1367 * @remark Used by and designed for kHtmlPC.
1368 */
1369BOOL _System dbFreeResult(void *pres)
1370{
1371 if (pres != NULL)
1372 mysql_free_result((MYSQL_RES*)pres);
1373 else
1374 return FALSE;
1375 return TRUE;
1376}
1377
1378
1379/**
1380 * Fetch data from a result. Returns the data by calling the given callback function.
1381 * @returns Success indicator, TRUE/FALSE.
1382 * @param pres Query result identifier/pointer.
1383 * @param dbFetchCallBack Callback-function.
1384 * @param pvUser User parameter which is passed onto dbFetchCallBack.
1385 * @remark Used by and designed for kHtmlPC.
1386 */
1387BOOL _System dbFetch(void *pres, DBCALLBACKFETCH dbFetchCallBack, void *pvUser)
1388{
1389 BOOL fRc = FALSE;
1390 MYSQL_ROW row = mysql_fetch_row((MYSQL_RES*)pres);
1391
1392 if (row)
1393 {
1394 MYSQL_FIELD *pField;
1395 int i = 0;
1396 mysql_field_seek((MYSQL_RES*)pres, 0);
1397
1398 while ((pField = mysql_fetch_field((MYSQL_RES*)pres)) != NULL)
1399 if (dbFetchCallBack(row[i++], pField->name, pvUser) != 0)
1400 return FALSE;
1401
1402 fRc = TRUE;
1403 }
1404
1405 return fRc;
1406}
1407
1408
1409/**
1410 * Converts an ISO date to days after Christ, year 0.
1411 * @returns days. -1 on error;
1412 * @param pszDate ISO Date.
1413 */
1414signed long _System dbDateToDaysAfterChrist(const char *pszDate)
1415{
1416 signed long lRet = -1;
1417 char szQuery[128];
1418
1419 sprintf(&szQuery[0], "SELECT to_days('%s')", pszDate);
1420 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1421 {
1422 MYSQL_ROW row;
1423 MYSQL_RES *pres = mysql_use_result(pmysql);
1424 row = mysql_fetch_row(pres);
1425 if (row != NULL)
1426 {
1427 lRet = atol(row[0]);
1428 do { row = mysql_fetch_row(pres); } while (row != NULL);
1429 }
1430 }
1431
1432 return lRet;
1433}
1434
1435
1436/**
1437 * Converts days after Christ (year 0) to ISO date.
1438 * @returns Success indicator. TRUE/FALSE;
1439 * @param lDays Days after Christ (year 0).
1440 * @param pszDate ISO Date. Result.
1441 */
1442BOOL _System dbDaysAfterChristToDate(signed long lDays, char *pszDate)
1443{
1444 BOOL fRet = FALSE;
1445 char szQuery[128];
1446
1447 if (lDays < 0)
1448 return FALSE;
1449
1450 sprintf(&szQuery[0], "SELECT from_days(%ld)", lDays);
1451 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1452 {
1453 MYSQL_ROW row;
1454 MYSQL_RES *pres = mysql_use_result(pmysql);
1455 row = mysql_fetch_row(pres);
1456 if (row != NULL)
1457 {
1458 fRet = strlen(row[0]) == (4+1+2+1+2) && row[0][4] == '-' && row[0][7] == '-'
1459 && strcmp(row[0], "0000-00-00") != 0;
1460 if (fRet)
1461 strcpy(pszDate, row[0]);
1462 do { row = mysql_fetch_row(pres); } while (row != NULL);
1463 }
1464 }
1465
1466 return fRet;
1467}
1468
1469
1470/**
1471 * Display all functions for, the given dll, that is not updated.
1472 * @returns TRUE / FALSE.
1473 * @param lDll Dll reference number.
1474 * @param dbFetchCall Callback function which will be called once for each
1475 * field for all the functions not updated.
1476 * pvUser is NULL, pszValue field value, pszFieldName the field name.
1477 */
1478BOOL _System dbGetNotUpdatedFunction(signed long lDll, DBCALLBACKFETCH dbFetchCallBack)
1479{
1480 BOOL fRet = FALSE;
1481 void *pres;
1482 char szQuery[256];
1483
1484 /* not updated names */
1485 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1486 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1487 " LEFT JOIN dll d ON f2.dll = d.refcode "
1488 "WHERE f1.dll = %ld AND f1.updated = 0",
1489 lDll);
1490 pres = dbExecuteQuery(szQuery);
1491 if (pres != NULL)
1492 {
1493 BOOL f;
1494 do
1495 {
1496 f = dbFetch(pres, dbFetchCallBack, NULL);
1497 } while (f);
1498 dbFreeResult(pres);
1499 fRet = TRUE;
1500 }
1501
1502 /* warn about updated > 1 too */
1503 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1504 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1505 " LEFT JOIN dll d ON f2.dll = d.refcode "
1506 "WHERE f1.dll = %ld AND f1.updated > 1",
1507 lDll);
1508 pres = dbExecuteQuery(szQuery);
1509 if (pres != NULL)
1510 {
1511 BOOL f;
1512 do
1513 {
1514 f = dbFetch(pres, dbFetchCallBack, NULL);
1515 } while (f);
1516 dbFreeResult(pres);
1517 fRet = TRUE;
1518 }
1519
1520 strcpy(&szQuery[0], "UPDATE function SET updated = 0");
1521 mysql_query(pmysql, &szQuery[0]);
1522
1523 return fRet;
1524}
1525
1526
1527/**
1528 * Counts the function for the given DLL which has been updated.
1529 * @returns -1 on error, number of updated function on success.
1530 * @param lDll Dll reference number.
1531 */
1532signed long _System dbGetNumberOfUpdatedFunction(signed long lDll)
1533{
1534 int rc;
1535 char szQuery[128];
1536 MYSQL_RES * pres;
1537
1538 sprintf(&szQuery[0], "SELECT count(*) FROM function WHERE dll = (%ld) AND updated > 0\n", lDll);
1539 rc = mysql_query(pmysql, &szQuery[0]);
1540 pres = mysql_store_result(pmysql);
1541 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
1542 rc = (int)getvalue(0, mysql_fetch_row(pres));
1543 else
1544 rc = -1;
1545 mysql_free_result(pres);
1546 return (signed long)rc;
1547}
1548
1549
1550#ifndef DLL
1551/**
1552 * Signal handler.
1553 * Ensures that the database connection is closed at termination.
1554 * @param sig Signal number.
1555 */
1556void dbHandler(int sig)
1557{
1558 if (pmysql != NULL)
1559 {
1560 fprintf(stderr, "\n\t!disconnecting from database!\n");
1561 dbDisconnect();
1562 }
1563
1564 flushall();
1565 switch (sig)
1566 {
1567 case SIGBREAK:
1568 printf("\nSIGBREAK\n");
1569 exit(-1);
1570 break;
1571 case SIGINT:
1572 printf("\nSIGINT\n");
1573 exit(-1);
1574 break;
1575 case SIGTERM:
1576 printf("\nSIGTERM\n");
1577 exit(-1);
1578 break;
1579 case SIGSEGV:
1580 raise(sig);
1581 break;
1582 case SIGILL:
1583 printf("\nSIGILL\n");
1584 exit(-1);
1585 break;
1586 }
1587}
1588
1589
1590#else
1591/*******/
1592/* DLL */
1593/*******/
1594/* prototypes used in the _DLL_InitTerm function */
1595extern "C"
1596{
1597 int _CRT_init(void);
1598 void _CRT_term(void);
1599 void __ctordtorInit( void );
1600 void __ctordtorTerm( void );
1601 unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag);
1602}
1603
1604
1605/**
1606 * Dll InitTerm function.
1607 * @returns 0 on success.
1608 * 1 on error.
1609 * @param hModule
1610 * @param ulFlags
1611 * @remark We'll ensure that the database connection is terminated as we terminate.
1612 */
1613unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag)
1614{
1615 /*-------------------------------------------------------------------------*/
1616 /* If ulFlag is zero then the DLL is being loaded so initialization should */
1617 /* be performed. If ulFlag is 1 then the DLL is being freed so */
1618 /* termination should be performed. */
1619 /*-------------------------------------------------------------------------*/
1620
1621 switch (ulFlag)
1622 {
1623 case 0:
1624 if (_CRT_init() == -1)
1625 return 0;
1626 __ctordtorInit();
1627 break;
1628
1629 case 1:
1630 /* ensure that db connection is terminated */
1631 if (pmysql != NULL)
1632 {
1633 fprintf(stderr, "\n\t!disconnecting from database!\n");
1634 dbDisconnect();
1635 }
1636 __ctordtorTerm();
1637 break;
1638
1639 default:
1640 return 0;
1641 }
1642 hModule = hModule;
1643 return 1;
1644}
1645
1646/*****************************************************************/
1647/* -why is this terminate function referenced but not defined??? */
1648/* and where is it referenced??? */
1649/* -Probably an export missing from the libraries. */
1650/*****************************************************************/
1651void terminate(void)
1652{
1653 DosPutMessage(0, sizeof("terminate")-1, "terminate");
1654 exit(-1);
1655}
1656
1657/****************************************/
1658/* EMX run-time trouble */
1659/* _environ is missing when using -Zomf */
1660/****************************************/
1661char **_environ = environ;
1662
1663#endif
Note: See TracBrowser for help on using the repository browser.