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

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

Corrections, DB optimizations, and some new features in StateUpd.

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