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

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

Some new reports.
General bugfixes and new features.

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