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

Last change on this file since 3841 was 3841, checked in by bird, 25 years ago

Implemented support for design notes and files.

File size: 70.9 KB
Line 
1/* $Id: db.cpp,v 1.14 2000-07-18 07:34:32 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);
82static char *sqlstrcat(char *pszQuery, const char *pszBefore, const char *pszStr, const char *pszAfter = NULL);
83
84#ifndef DLL
85 extern "C" void dbHandler(int sig);
86#endif
87
88
89/**
90 * Gets the descriptions of the last database error.
91 * @returns Readonly string.
92 */
93char * _System dbGetLastErrorDesc(void)
94{
95 return mysql_error(&mysql);
96}
97
98
99/**
100 * Connects to local database.
101 * @returns Success indicator, TRUE / FALSE.
102 * @param pszDatabase Name of database to use.
103 */
104BOOL _System dbConnect(const char *pszHost, const char *pszUser, const char *pszPassword, const char *pszDatabase)
105{
106 BOOL fRet = FALSE;
107 #ifndef DLL
108 static fHandler = FALSE;
109 /* signal handler */
110 if (!fHandler)
111 {
112 if ( SIG_ERR == signal(SIGBREAK, dbHandler)
113 || SIG_ERR == signal(SIGINT, dbHandler)
114 || SIG_ERR == signal(SIGTERM, dbHandler)
115 || SIG_ERR == signal(SIGABRT, dbHandler)
116 || SIG_ERR == signal(SIGSEGV, dbHandler)
117 || SIG_ERR == signal(SIGILL, dbHandler)
118 )
119 fprintf(stderr, "Error installing signalhandler...");
120 else
121 fHandler = TRUE;
122 }
123 #endif
124
125 /* connect to server */
126 memset(&mysql, 0, sizeof(mysql));
127 pmysql = mysql_connect(&mysql, pszHost, pszUser, pszPassword);
128 if (pmysql != NULL)
129 {
130 /* connect to database */
131 fRet = mysql_select_db(pmysql, pszDatabase) >= 0;
132 if (fRet)
133 mysql_refresh(pmysql, REFRESH_TABLES);
134 }
135
136 return fRet;
137}
138
139
140/**
141 * Disconnects from database.
142 * @returns Success indicator. TRUE / FALSE.
143 */
144BOOL _System dbDisconnect(void)
145{
146 if (pmysql != NULL)
147 {
148 mysql_refresh(pmysql, REFRESH_TABLES);
149 mysql_close(pmysql);
150 pmysql = NULL;
151 }
152 return TRUE;
153}
154
155/**
156 * Gets the refid for the give dll name.
157 * @returns Dll refid. -1 on error.
158 * @param pszDllName Dll name.
159 */
160signed short _System dbGetDll(const char *pszDllName)
161{
162 int rc;
163 char szQuery[256];
164 MYSQL_RES * pres;
165
166 sprintf(&szQuery[0], "SELECT refcode FROM dll WHERE name = '%s'\n", pszDllName);
167 rc = mysql_query(pmysql, &szQuery[0]);
168 pres = mysql_store_result(pmysql);
169
170 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
171 rc = (int)getvalue(0, mysql_fetch_row(pres));
172 else
173 rc = -1;
174 mysql_free_result(pres);
175 return (short)rc;
176}
177
178
179/**
180 * Count the function in a given dll.
181 * @returns Number of functions. -1 on error.
182 * @param usDll Dll refcode.
183 * @param fNotAliases TRUE: don't count aliased functions.
184 */
185signed long _System dbCountFunctionInDll(signed long ulDll, BOOL fNotAliases)
186{
187 signed long rc;
188 char szQuery[256];
189 MYSQL_RES * pres;
190
191 if (ulDll >= 0)
192 {
193 sprintf(&szQuery[0], "SELECT count(refcode) FROM function WHERE dll = %ld\n", ulDll);
194 if (fNotAliases)
195 strcat(&szQuery[0], " AND aliasfn < 0");
196 rc = mysql_query(pmysql, &szQuery[0]);
197 pres = mysql_store_result(pmysql);
198
199 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
200 rc = (int)getvalue(0, mysql_fetch_row(pres));
201 else
202 rc = -1;
203 mysql_free_result(pres);
204 }
205 else
206 rc = -1;
207 return rc;
208}
209
210
211
212/**
213 * Checks if dll exists. If not exists the dll is inserted.
214 * @returns Dll refcode. -1 on errors.
215 * @param pszDll Dll name.
216 * @remark This search must be case insensitive.
217 * (In the mysql-world everything is case insensitive!)
218 */
219signed short _System dbCheckInsertDll(const char *pszDll)
220{
221 int rc;
222 char szQuery[256];
223 MYSQL_RES * pres;
224
225 /* try find match */
226 sprintf(&szQuery[0], "SELECT refcode, name FROM dll WHERE name = '%s'\n", pszDll);
227 rc = mysql_query(pmysql, &szQuery[0]);
228 pres = mysql_store_result(pmysql);
229
230 /* not found? - insert dll */
231 if (rc < 0 || pres == NULL || mysql_num_rows(pres) == 0)
232 {
233 mysql_free_result(pres);
234
235 sprintf(&szQuery[0], "INSERT INTO dll(name) VALUES('%s')\n", pszDll);
236 rc = mysql_query(pmysql, &szQuery[0]);
237
238 /* select row to get refcode */
239 sprintf(&szQuery[0], "SELECT refcode, name FROM dll WHERE name = '%s'\n", pszDll);
240 rc = mysql_query(pmysql, &szQuery[0]);
241 pres = mysql_store_result(pmysql);
242 }
243
244 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
245 rc = (int)getvalue(0, mysql_fetch_row(pres));
246 else
247 rc = -1;
248 mysql_free_result(pres);
249
250 return (short)rc;
251}
252
253
254/**
255 * Simple select for a long value.
256 * @returns long value
257 * @param pszTable From part.
258 * @param pszGetColumn Name of column to retreive.
259 * @param pszMatch1 Match column/expression
260 * @param pszMatchValue1 Match value.
261 * @remark Dirty! Don't use this!
262 */
263unsigned short _System dbGet(const char *pszTable, const char *pszGetColumn,
264 const char *pszMatch1, const char *pszMatchValue1)
265{
266 int rc;
267 char szQuery[256];
268 MYSQL_RES *pres;
269
270 /* try find match */
271 sprintf(&szQuery[0], "SELECT %s FROM %s WHERE %s = '%s'\n",
272 pszGetColumn, pszTable, pszMatch1, pszMatchValue1);
273 rc = mysql_query(pmysql, &szQuery[0]);
274 pres = mysql_store_result(pmysql);
275
276 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
277 rc = (int)getvalue(0, mysql_fetch_row(pres));
278 else
279 rc = -1;
280 mysql_free_result(pres);
281
282 return (short)rc;
283}
284
285
286/**
287 * Updates or inserts a function name into the database.
288 * @returns Success indicator. TRUE / FALSE.
289 * @param usDll Dll refcode.
290 * @param pszFunction Function name.
291 * @param pszIntFunction Internal function name. (required!)
292 * @param ulOrdinal Ordinal value.
293 * @param fIgnoreOrdinal Do not update ordinal value.
294 */
295BOOL _System dbInsertUpdateFunction(unsigned short usDll,
296 const char *pszFunction, const char *pszIntFunction,
297 unsigned long ulOrdinal, BOOL fIgnoreOrdinal)
298{
299 int rc;
300 long lFunction = -1;
301 char szQuery[512];
302 MYSQL_RES *pres;
303
304 /* when no internal name fail! */
305 if (pszIntFunction == NULL || *pszIntFunction == '\0')
306 return FALSE;
307
308 /* try find function */
309 sprintf(&szQuery[0], "SELECT refcode, intname FROM function WHERE dll = %d AND name = '%s'", usDll, pszFunction);
310 rc = mysql_query(pmysql, &szQuery[0]);
311 pres = mysql_store_result(pmysql);
312 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) != 0)
313 { /* update function (function is found) */
314 MYSQL_ROW parow;
315 if (mysql_num_rows(pres) > 1)
316 {
317 fprintf(stderr, "internal database integrity error(%s): More function by the same name for the same dll. "
318 "usDll = %d, pszFunction = %s\n", __FUNCTION__, usDll, pszFunction);
319 return FALSE;
320 }
321
322 parow = mysql_fetch_row(pres);
323 if (parow != NULL)
324 lFunction = getvalue(0, parow);
325 mysql_free_result(pres);
326
327 if (strcmp(parow[1], pszIntFunction) != 0)
328 {
329 sprintf(&szQuery[0], "UPDATE function SET intname = '%s' WHERE refcode = %ld",
330 pszIntFunction, lFunction);
331 rc = mysql_query(pmysql, &szQuery[0]);
332 }
333
334 if (rc >= 0 && !fIgnoreOrdinal)
335 {
336 sprintf(&szQuery[0], "UPDATE function SET ordinal = %ld WHERE refcode = %ld",
337 ulOrdinal, lFunction);
338 rc = mysql_query(pmysql, &szQuery[0]);
339 }
340
341 }
342 else
343 { /* insert */
344 sprintf(&szQuery[0], "INSERT INTO function(dll, name, intname, ordinal) VALUES(%d, '%s', '%s', %ld)",
345 usDll, pszFunction, pszIntFunction, ulOrdinal);
346 rc = mysql_query(pmysql, &szQuery[0]);
347 }
348
349 return rc >= 0;
350}
351
352
353
354/**
355 * Inserts or updates (existing) file information.
356 * @returns Success indicator (TRUE / FALSE).
357 * @param usDll Dll reference code.
358 * @param pszFilename Filename.
359 * @param pszDescription Pointer to file description.
360 * @param pszLastDateTime Date and time for last change (ISO).
361 * @param lLastAuthor Author number. (-1 if not found.)
362 * @param pszRevision Pointer to revision string.
363 * @sketch
364 * @remark
365 */
366BOOL _System dbInsertUpdateFile(unsigned short usDll,
367 const char *pszFilename,
368 const char *pszDescription,
369 const char *pszLastDateTime,
370 signed long lLastAuthor,
371 const char *pszRevision)
372{
373 int rc;
374 long lFile = -1;
375 char szQuery[0x10000];
376 MYSQL_RES *pres;
377
378 /* parameter assertions */
379 assert(usDll != 0);
380 assert(pszFilename != NULL);
381 assert(*pszFilename != '\0');
382
383 /* try find file */
384 sprintf(&szQuery[0], "SELECT refcode, name FROM file WHERE dll = %d AND name = '%s'", usDll, pszFilename);
385 rc = mysql_query(pmysql, &szQuery[0]);
386 pres = mysql_store_result(pmysql);
387 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) != 0)
388 { /* update file (file is found) */
389 MYSQL_ROW parow;
390 if (mysql_num_rows(pres) > 1)
391 {
392 fprintf(stderr, "internal database integrity error(%s): More files by the same name in the same dll. "
393 "usDll = %d, pszFilename = %s\n", __FUNCTION__, usDll, pszFilename);
394 return FALSE;
395 }
396
397 parow = mysql_fetch_row(pres);
398 if (parow != NULL)
399 lFile = getvalue(0, parow);
400 mysql_free_result(pres);
401
402 if (strcmp(parow[1], pszFilename) != 0) /* case might have changed... */
403 {
404 sprintf(&szQuery[0], "UPDATE file SET name = '%s' WHERE refcode = %ld",
405 pszFilename, lFile);
406 rc = mysql_query(pmysql, &szQuery[0]);
407 }
408
409 if (rc >= 0)
410 {
411 if (pszDescription != NULL && pszDescription != '\0')
412 {
413 szQuery[0] = '\0';
414 sqlstrcat(&szQuery[0], "UPDATE file SET description = ", pszDescription, NULL);
415 sprintf(&szQuery[strlen(szQuery)], " WHERE refcode = %ld", lFile);
416 }
417 else
418 sprintf(&szQuery[0], "UPDATE file SET description = NULL WHERE refcode = %ld",
419 lFile);
420 rc = mysql_query(pmysql, &szQuery[0]);
421 }
422
423 if (rc >= 0 && pszLastDateTime != NULL && *pszLastDateTime != '\0')
424 {
425 sprintf(&szQuery[0], "UPDATE file SET lastdatetime = '%s' WHERE refcode = %ld",
426 pszLastDateTime, lFile);
427 rc = mysql_query(pmysql, &szQuery[0]);
428 }
429
430 if (rc >= 0)
431 {
432 sprintf(&szQuery[0], "UPDATE file SET lastauthor = %ld WHERE refcode = %ld",
433 lLastAuthor, lFile);
434 rc = mysql_query(pmysql, &szQuery[0]);
435 }
436
437 if (rc >= 0 && pszRevision != NULL && *pszRevision != '\0')
438 {
439 sprintf(&szQuery[0], "UPDATE file SET revision = '%s' WHERE refcode = %ld",
440 pszRevision, lFile);
441 rc = mysql_query(pmysql, &szQuery[0]);
442 }
443
444 }
445 else
446 { /* insert */
447 sprintf(&szQuery[0], "INSERT INTO file(dll, name, description, lastauthor, lastdatetime, revision) VALUES(%d, '%s', %ld, ",
448 usDll, pszFilename, lLastAuthor);
449 if (pszDescription != NULL && *pszDescription != '\0')
450 sqlstrcat(&szQuery[0], NULL, pszDescription);
451 else
452 strcat(&szQuery[0], "NULL");
453
454 if (pszLastDateTime != NULL && *pszLastDateTime != '\0')
455 sqlstrcat(&szQuery[0], ", ", pszLastDateTime);
456 else
457 strcat(&szQuery[0], ", '1975-03-13 14:00:00'"); /* dummy */
458
459 if (pszRevision != NULL && *pszRevision != '\0')
460 sqlstrcat(&szQuery[0], ", ", pszRevision, ")");
461 else
462 strcat(&szQuery[0], ", '')");
463
464 rc = mysql_query(pmysql, &szQuery[0]);
465 }
466
467 return rc >= 0;
468}
469
470
471/**
472 * Get a long value.
473 * @returns Number value of pRow[iField]. -1 on error.
474 * @param iField Index into pRow.
475 * @param pRow Pointer to array (of string pointers).
476 */
477static long getvalue(int iField, MYSQL_ROW papszRow)
478{
479 if (papszRow[iField] != NULL)
480 return atol((char*)papszRow[iField]);
481
482 return -1;
483}
484
485
486#if 0
487/*
488 * Stubs used while optimizing sqls.
489 */
490int mysql_query1(MYSQL *mysql, const char *q)
491{ return mysql_query(mysql, q); }
492int mysql_query2(MYSQL *mysql, const char *q)
493{ return mysql_query(mysql, q); }
494int mysql_query3(MYSQL *mysql, const char *q)
495{ return mysql_query(mysql, q); }
496int mysql_query4(MYSQL *mysql, const char *q)
497{ return mysql_query(mysql, q); }
498int mysql_query5(MYSQL *mysql, const char *q)
499{ return mysql_query(mysql, q); }
500int mysql_query6(MYSQL *mysql, const char *q)
501{ return mysql_query(mysql, q); }
502
503#else
504
505#define mysql_query1 mysql_query
506#define mysql_query2 mysql_query
507#define mysql_query3 mysql_query
508#define mysql_query4 mysql_query
509#define mysql_query5 mysql_query
510#define mysql_query6 mysql_query
511
512#endif
513
514
515
516/**
517 * Find occurences of a function, given by internal name.
518 * @returns success indicator, TRUE / FALSE.
519 * @param pszFunctionName Pointer to a function name string. (input)
520 * @param pFnFindBuf Pointer to a find buffer. (output)
521 * @param lDll Dll refcode (optional). If given the search is limited to
522 * the given dll and aliasing functions is updated (slow!).
523 * @sketch 1) Get functions for this dll(if given).
524 * 2) Get functions which aliases the functions found in (1).
525 * 3) Get new aliases by intname
526 * 4) Get new aliases by name
527 * 5) Update all functions from (1) to have aliasfn -2 (DONTMIND)
528 * 6) Update all functions from (3) and (4) to alias the first function from 1.
529 */
530BOOL _System dbFindFunction(const char *pszFunctionName, PFNFINDBUF pFnFindBuf, signed long lDll)
531{
532 MYSQL_RES *pres;
533 MYSQL_ROW row;
534 int rc;
535 char szQuery[1024];
536
537 /*
538 * 1) Get functions for this dll(if given).
539 */
540 if (lDll < 0)
541 sprintf(&szQuery[0], "SELECT refcode, dll, aliasfn, file, name FROM function WHERE intname = '%s'",
542 pszFunctionName);
543 else
544 sprintf(&szQuery[0], "SELECT refcode, dll, aliasfn, file, name FROM function "
545 "WHERE intname = '%s' AND dll = %ld",
546 pszFunctionName, lDll);
547
548 rc = mysql_query1(pmysql, &szQuery[0]);
549 if (rc >= 0)
550 {
551 pres = mysql_store_result(pmysql);
552 if (pres != NULL)
553 {
554 char szFnName[NBR_FUNCTIONS][80];
555
556 pFnFindBuf->cFns = 0;
557 while ((row = mysql_fetch_row(pres)) != NULL)
558 {
559 pFnFindBuf->alRefCode[pFnFindBuf->cFns] = atol(row[0]);
560 pFnFindBuf->alDllRefCode[pFnFindBuf->cFns] = atol(row[1]);
561 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = atol(row[2]);
562 pFnFindBuf->alFileRefCode[pFnFindBuf->cFns] = atol(row[3]);
563 strcpy(szFnName[pFnFindBuf->cFns], row[4]);
564
565 /* next */
566 pFnFindBuf->cFns++;
567 }
568 mysql_free_result(pres);
569
570 /* alias check and fix */
571 if (lDll >= 0 && pFnFindBuf->cFns != 0)
572 {
573 int cFnsThisDll, cFnsAliasesAndThisDll, i, f;
574
575 /*
576 * 2) Get functions which aliases the functions found in (1).
577 */
578 cFnsThisDll = (int)pFnFindBuf->cFns;
579 strcpy(&szQuery[0], "SELECT refcode, dll, aliasfn, file, name FROM function WHERE aliasfn IN (");
580 for (i = 0; i < cFnsThisDll; i++)
581 {
582 if (i > 0) strcat(&szQuery[0], " OR ");
583 sprintf(&szQuery[strlen(szQuery)], "(%ld)", pFnFindBuf->alRefCode[i]);
584 }
585 strcat(&szQuery[0], ")");
586
587 rc = mysql_query2(pmysql, &szQuery[0]);
588 if (rc >= 0)
589 {
590 pres = mysql_store_result(pmysql);
591 if (pres != NULL)
592 {
593 while ((row = mysql_fetch_row(pres)) != NULL)
594 {
595 pFnFindBuf->alRefCode[pFnFindBuf->cFns] = atol(row[0]);
596 pFnFindBuf->alDllRefCode[pFnFindBuf->cFns] = atol(row[1]);
597 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = atol(row[2]);
598 pFnFindBuf->alFileRefCode[pFnFindBuf->cFns] = atol(row[3]);
599 strcpy(szFnName[pFnFindBuf->cFns], row[4]);
600
601 /* next */
602 pFnFindBuf->cFns++;
603 }
604 mysql_free_result(pres);
605
606 /*
607 * 3) Get new aliases by intname
608 */
609 cFnsAliasesAndThisDll = (int)pFnFindBuf->cFns;
610 sprintf(&szQuery[0], "SELECT refcode, dll, aliasfn, file FROM function "
611 "WHERE aliasfn = (-1) AND dll <> %ld AND (intname = '%s'",
612 lDll, pszFunctionName);
613 for (i = 0; i < cFnsAliasesAndThisDll; i++)
614 sprintf(&szQuery[strlen(&szQuery[0])], " OR intname = '%s'", szFnName[i]);
615 strcat(&szQuery[0], ")");
616
617 rc = mysql_query3(pmysql, &szQuery[0]);
618 if (rc >= 0)
619 {
620 pres = mysql_store_result(pmysql);
621 if (pres != NULL)
622 {
623 while ((row = mysql_fetch_row(pres)) != NULL)
624 {
625 pFnFindBuf->alRefCode[pFnFindBuf->cFns] = atol(row[0]);
626 pFnFindBuf->alDllRefCode[pFnFindBuf->cFns] = atol(row[1]);
627 if (row[2] != NULL)
628 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = atol(row[2]);
629 else
630 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = ALIAS_NULL;
631 pFnFindBuf->alFileRefCode[pFnFindBuf->cFns] = atol(row[3]);
632
633 /* next */
634 pFnFindBuf->cFns++;
635 }
636 mysql_free_result(pres);
637
638
639 /*
640 * 4) Get new aliases by name
641 */
642 sprintf(&szQuery[0], "SELECT refcode, dll, aliasfn, file FROM function "
643 "WHERE aliasfn = (-1) AND dll <> %ld AND (name = '%s'",
644 lDll, pszFunctionName);
645 for (i = 0; i < cFnsAliasesAndThisDll; i++)
646 sprintf(&szQuery[strlen(&szQuery[0])], " OR name = '%s'", szFnName[i]);
647 strcat(&szQuery[0], ")");
648
649 rc = mysql_query4(pmysql, &szQuery[0]);
650 if (rc >= 0)
651 {
652 pres = mysql_store_result(pmysql);
653 if (pres != NULL)
654 {
655 while ((row = mysql_fetch_row(pres)) != NULL)
656 {
657 pFnFindBuf->alRefCode[pFnFindBuf->cFns] = atol(row[0]);
658 pFnFindBuf->alDllRefCode[pFnFindBuf->cFns] = atol(row[1]);
659 if (row[2] != NULL)
660 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = atol(row[2]);
661 else
662 pFnFindBuf->alAliasFn[pFnFindBuf->cFns] = ALIAS_NULL;
663 pFnFindBuf->alFileRefCode[pFnFindBuf->cFns] = atol(row[3]);
664
665 /* next */
666 pFnFindBuf->cFns++;
667 }
668 mysql_free_result(pres);
669
670 /*
671 * 5) Update all functions from (1) to have aliasfn -2 (DONTMIND)
672 */
673 sprintf(&szQuery[0], "UPDATE function SET aliasfn = (-2) "
674 "WHERE refcode IN (",
675 lDll, pszFunctionName);
676 for (f = 0, i = 0; i < cFnsThisDll; i++)
677 if (pFnFindBuf->alAliasFn[i] != ALIAS_DONTMIND)
678 sprintf(&szQuery[strlen(&szQuery[0])],
679 f++ != 0 ? ", %ld" : "%ld", pFnFindBuf->alRefCode[i]);
680 strcat(&szQuery[0], ") AND aliasfn <> (-2)");
681 if (f > 0)
682 rc = mysql_query5(pmysql, &szQuery[0]);
683 else
684 rc = 0;
685 if (rc >= 0 && cFnsAliasesAndThisDll < pFnFindBuf->cFns)
686 {
687 /*
688 * 6) Update all functions from (3) and (4) to alias the first function from 1.
689 */
690 sprintf(&szQuery[0], "UPDATE function SET aliasfn = (%ld), file = (%ld) "
691 "WHERE aliasfn = (-1) AND refcode IN (",
692 pFnFindBuf->alRefCode[0], pFnFindBuf->alFileRefCode[0]);
693 for (i = cFnsAliasesAndThisDll; i < pFnFindBuf->cFns; i++)
694 {
695 sprintf(&szQuery[strlen(&szQuery[0])],
696 i > cFnsAliasesAndThisDll ? ", %ld" : "%ld", pFnFindBuf->alRefCode[i]);
697 }
698 strcat(&szQuery[0], ")");
699 rc = mysql_query6(pmysql, &szQuery[0]);
700 } /* query 5 */
701 }
702 } /* query 4 */
703 }
704 } /* query 3 */
705 }
706 } /* query 2 */
707 }
708 } /* query 1 */
709 else
710 rc = -1;
711 }
712
713 return rc >= 0;
714}
715
716
717/**
718 * Finds the refcode for a file (if it exists).
719 * @returns File 'refcode'.
720 * -1 on error or not found.
721 * @param lDll Refcode of the dll which this file belongs to.
722 * @param pszFilename The filename to search for.
723 */
724signed long _System dbFindFile(signed long lDll, const char *pszFilename)
725{
726 char szQuery[256];
727 MYSQL_RES * pres;
728 signed long lRefCode = -1;
729
730 assert(lDll >= 0);
731 assert(pszFilename != NULL);
732 assert(*pszFilename != '\0');
733
734 sprintf(&szQuery[0], "SELECT refcode FROM file WHERE dll = %ld AND name = '%s'",
735 lDll, pszFilename);
736 if (mysql_query(pmysql, &szQuery[0]) >= 0)
737 {
738 pres = mysql_store_result(pmysql);
739 if (pres != NULL)
740 {
741 MYSQL_ROW parow = mysql_fetch_row(pres);
742 if (parow != NULL)
743 lRefCode = getvalue(0, parow);
744 mysql_free_result(pres);
745 }
746 }
747
748 return lRefCode;
749}
750
751
752/**
753 * Finds the refcode for an author, if the author exists.
754 * @returns Author 'refcode'.
755 * @param pszAuthor String which holds the identifier of an author.
756 * This doesn't have to be the name. Initials, alias and email
757 * is also searched.
758 * @param pszEmail Email address. Might be NULL!
759 */
760signed long _System dbFindAuthor(const char *pszAuthor, const char *pszEmail)
761{
762 signed long refcode = -1;
763 MYSQL_RES *pres;
764 char szQuery[512];
765
766 /*
767 * parameter validations
768 */
769 if (pszAuthor == NULL || strlen(pszAuthor) > 64)
770 return -1;
771 if (pszEmail != NULL && strlen(pszEmail) > 64)
772 {
773 fprintf(stderr, "email too long!");
774 return -1;
775 }
776
777 /*
778 * Query
779 */
780 sprintf(&szQuery[0],
781 "SELECT refcode FROM author "
782 "WHERE name = '%s' OR "
783 " initials = '%s' OR "
784 " alias = '%s' OR "
785 " email = '%s'",
786 pszAuthor, pszAuthor, pszAuthor, pszAuthor);
787
788 if (pszEmail != NULL)
789 sprintf(&szQuery[strlen(&szQuery[0])], " OR email = '%s'", pszEmail);
790
791 if (mysql_query(pmysql, &szQuery[0]) >= 0)
792 {
793 pres = mysql_store_result(pmysql);
794 if (pres != NULL)
795 {
796 MYSQL_ROW parow;
797
798 /* integrety check */
799 if (mysql_num_rows(pres) > 1)
800 fprintf(stderr, "Integrety: author '%s' is not unique!\n", pszAuthor);
801 parow = mysql_fetch_row(pres);
802 if (parow != NULL)
803 refcode = getvalue(0, parow);
804
805 mysql_free_result(pres);
806 }
807 }
808
809 return refcode;
810}
811
812
813/**
814 * Gets the state of a function.
815 * @returns state code. On error -1.
816 * @param lRefCode Function refcode.
817 */
818signed long _System dbGetFunctionState(signed long lRefCode)
819{
820 signed long lState = -1;
821 MYSQL_RES *pres;
822 char szQuery[128];
823
824 sprintf(&szQuery[0], "SELECT state FROM function WHERE refcode = %ld", lRefCode);
825 if (mysql_query(pmysql, &szQuery[0]) >= 0)
826 {
827 pres = mysql_store_result(pmysql);
828 if (pres != NULL)
829 {
830 MYSQL_ROW parow = mysql_fetch_row(pres);
831 if (parow != NULL)
832 lState = getvalue(0, parow);
833 mysql_free_result(pres);
834 }
835 }
836
837 return lState;
838}
839
840#if 1
841/*
842 * Stubs used while optimizing sqls.
843 */
844int mysql_queryu1(MYSQL *mysql, const char *q)
845{ return mysql_query(mysql, q); }
846int mysql_queryu2(MYSQL *mysql, const char *q)
847{ return mysql_query(mysql, q); }
848int mysql_queryu3(MYSQL *mysql, const char *q)
849{ return mysql_query(mysql, q); }
850int mysql_queryu4(MYSQL *mysql, const char *q)
851{ return mysql_query(mysql, q); }
852int mysql_queryu5(MYSQL *mysql, const char *q)
853{ return mysql_query(mysql, q); }
854int mysql_queryu6(MYSQL *mysql, const char *q)
855{ return mysql_query(mysql, q); }
856int mysql_queryu7(MYSQL *mysql, const char *q)
857{ return mysql_query(mysql, q); }
858int mysql_queryu8(MYSQL *mysql, const char *q)
859{ return mysql_query(mysql, q); }
860#else
861#define mysql_queryu1 mysql_query
862#define mysql_queryu2 mysql_query
863#define mysql_queryu3 mysql_query
864#define mysql_queryu4 mysql_query
865#define mysql_queryu5 mysql_query
866#define mysql_queryu6 mysql_query
867#define mysql_queryu7 mysql_query
868#define mysql_queryu8 mysql_query
869#endif
870
871/**
872 * Updates function information.
873 * @returns number of errors.
874 * @param pFnDesc Function description struct.
875 * @param lDll Dll which we are working at.
876 * @param pszError Buffer for error messages
877 * @result on error(s) pszError will hold information about the error(s).
878 */
879unsigned long _System dbUpdateFunction(PFNDESC pFnDesc, signed long lDll, char *pszError)
880{
881 MYSQL_RES * pres;
882 MYSQL_ROW row;
883 char * pszQuery2 = (char*)malloc(65500);
884 char * pszQuery = pszQuery2;
885 long lCurrentState;
886 int i,k,rc;
887 unsigned long ulRc = 0;
888
889 /* check if malloc have failed allocating memory for us. */
890 if (pszQuery2 == NULL)
891 {
892 strcpy(pszError, "internal dbUpdateFunction error - malloc failed!\n");
893 return 1;
894 }
895
896
897 /*
898 * Loop thru all functions in the array of refocodes.
899 */
900 for (k = 0; k < pFnDesc->cRefCodes; k++)
901 {
902 BOOL f = FALSE;
903
904 /*
905 * Set updated flag
906 */
907 sprintf(pszQuery, "UPDATE function SET updated = updated + 1 WHERE refcode = %ld",
908 pFnDesc->alRefCode[k]);
909 rc = mysql_queryu1(pmysql, pszQuery2);
910
911
912 /*
913 * Get current status
914 */
915 lCurrentState = dbGetFunctionState(pFnDesc->alRefCode[k]);
916 if (lCurrentState == -1 && dbGetLastErrorDesc() != NULL && strlen(dbGetLastErrorDesc()) != 0)
917 {
918 strcpy(pszError, dbGetLastErrorDesc());
919 free(pszQuery2);
920 return 1;
921 }
922
923
924 /*
925 * Update function table first
926 */
927 strcpy(pszQuery, "UPDATE function SET ");
928 pszQuery += strlen(pszQuery);
929
930 /* Status */
931 if (lCurrentState != pFnDesc->lStatus
932 && pFnDesc->lStatus != 0
933 && (lCurrentState == 0 || pFnDesc->lStatus != 99))
934 {
935 sprintf(pszQuery, "state = %ld", pFnDesc->lStatus);
936 f = TRUE;
937 }
938 pszQuery += strlen(pszQuery);
939
940 /* return type */
941 if (pFnDesc->pszReturnType != NULL)
942 {
943 if (f) strcat(pszQuery, ", ");
944 pszQuery = sqlstrcat(pszQuery, "return = ", pFnDesc->pszReturnType);
945 f = TRUE;
946 }
947
948 /* Description */
949 if (pFnDesc->pszDescription != NULL)
950 {
951 if (f) strcat(pszQuery, ", ");
952 pszQuery = sqlstrcat(pszQuery, "description = ", pFnDesc->pszDescription);
953 f = TRUE;
954 }
955
956 /* Remark */
957 if (pFnDesc->pszRemark != NULL)
958 {
959 if (f) strcat(pszQuery, ", ");
960 pszQuery = sqlstrcat(pszQuery, "remark = ", pFnDesc->pszRemark);
961 f = TRUE;
962 }
963
964 /* Description */
965 if (pFnDesc->pszReturnDesc != NULL)
966 {
967 if (f) strcat(pszQuery, ", ");
968 pszQuery = sqlstrcat(pszQuery, "returndesc = ", pFnDesc->pszReturnDesc);
969 f = TRUE;
970 }
971
972 /* Sketch */
973 if (pFnDesc->pszSketch != NULL)
974 {
975 if (f) strcat(pszQuery, ", ");
976 pszQuery = sqlstrcat(pszQuery, "sketch = ", pFnDesc->pszSketch);
977 f = TRUE;
978 }
979
980 /* Equiv */
981 if (pFnDesc->pszEquiv != NULL)
982 {
983 if (f) strcat(pszQuery, ", ");
984 pszQuery = sqlstrcat(pszQuery, "equiv = ", pFnDesc->pszEquiv);
985 f = TRUE;
986 }
987
988 /* Equiv */
989 if (pFnDesc->pszTime != NULL)
990 {
991 if (f) strcat(pszQuery, ", ");
992 pszQuery = sqlstrcat(pszQuery, "time = ", pFnDesc->pszTime);
993 f = TRUE;
994 }
995
996 /* Execute update query? */
997 if (f)
998 {
999 sprintf(pszQuery + strlen(pszQuery), " WHERE refcode = %ld", pFnDesc->alRefCode[k]);
1000 rc = mysql_queryu2(pmysql, pszQuery2);
1001 if (rc < 0)
1002 {
1003 sprintf(pszError, "Updating functiontable failed with error: %s - (sql=%s) ",
1004 dbGetLastErrorDesc(), pszQuery2);
1005 pszError += strlen(pszError) - 1;
1006 ulRc++;
1007 }
1008 }
1009
1010
1011
1012 /*
1013 * Parameters
1014 */
1015 pszQuery = pszQuery2;
1016 sprintf(pszQuery, "SELECT count(*) FROM parameter WHERE function = %ld", pFnDesc->alRefCode[k]);
1017 rc = mysql_queryu3(pmysql, pszQuery);
1018 if (rc >= 0)
1019 {
1020 pres = mysql_store_result(pmysql);
1021 if (pres != NULL)
1022 row = mysql_fetch_row(pres);
1023 if (pres != NULL && row != NULL && mysql_num_rows(pres) == 1)
1024 {
1025 if (atol(row[0]) == pFnDesc->cParams)
1026 { /* update parameters */
1027 for (i = 0; i < pFnDesc->cParams; i++)
1028 {
1029 sprintf(pszQuery, "UPDATE parameter SET type = '%s', name = '%s'",
1030 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
1031 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : "");
1032 if (pFnDesc->apszParamDesc[i] != NULL)
1033 sqlstrcat(pszQuery, ", description = ", pFnDesc->apszParamDesc[i]);
1034 sprintf(pszQuery + strlen(pszQuery), " WHERE function = (%ld) AND sequencenbr = (%ld)",
1035 pFnDesc->alRefCode[k], i);
1036 rc = mysql_queryu4(pmysql, pszQuery);
1037 if (rc < 0)
1038 {
1039 if (*pszError == ' ')
1040 strcpy(pszError++, "\n\t");
1041 sprintf(pszError, "Updateing parameter %i failed with error: %s - (sql=%s) ",
1042 i, dbGetLastErrorDesc(), pszQuery);
1043 pszError += strlen(pszError) - 1;
1044 ulRc++;
1045 }
1046 }
1047 }
1048 else
1049 {
1050 if (atol(row[0]) != 0)
1051 { /* delete old parameters */
1052 sprintf(pszQuery, "DELETE FROM parameter WHERE function = %ld", pFnDesc->alRefCode[k]);
1053 rc = mysql_queryu5(pmysql, pszQuery);
1054 if (rc < 0)
1055 {
1056 if (*pszError == ' ')
1057 strcpy(pszError++, "\n\t");
1058 sprintf(pszError, "Deleting old parameters failed with error: %s - (sql=%s) ",
1059 dbGetLastErrorDesc(), pszQuery);
1060 pszError += strlen(pszError) - 1;
1061 ulRc++;
1062 }
1063 }
1064
1065 /* insert parameters */
1066 for (i = 0; i < pFnDesc->cParams; i++)
1067 {
1068 sprintf(pszQuery, "INSERT INTO parameter(function, sequencenbr, type, name, description) "
1069 "VALUES (%ld, %d, '%s', '%s'",
1070 pFnDesc->alRefCode[k], i,
1071 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
1072 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : ""
1073 );
1074 if (pFnDesc->apszParamDesc[i] != NULL)
1075 sqlstrcat(pszQuery, ", ", pFnDesc->apszParamDesc[i]);
1076 else
1077 strcat(pszQuery, ", NULL)");
1078
1079 rc = mysql_queryu6(pmysql, pszQuery2);
1080 if (rc < 0)
1081 {
1082 if (*pszError == ' ')
1083 strcpy(pszError++, "\n\t");
1084 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
1085 i, dbGetLastErrorDesc(), pszQuery);
1086 pszError += strlen(pszError) - 1;
1087 ulRc++;
1088 }
1089 }
1090 }
1091 }
1092 else
1093 {
1094 if (*pszError == ' ')
1095 strcpy(pszError++, "\n\t");
1096 sprintf(pszError, "failed to store result or to fetch a row , error: %s - (sql=%s) ",
1097 dbGetLastErrorDesc(), pszQuery);
1098 pszError += strlen(pszError) - 1;
1099 ulRc++;
1100 }
1101 }
1102 else
1103 {
1104 if (*pszError == ' ')
1105 strcpy(pszError++, "\n\t");
1106 sprintf(pszError, "Failed querying number of parameters, error: %s - (sql=%s) ",
1107 dbGetLastErrorDesc(), pszQuery);
1108 pszError += strlen(pszError) - 1;
1109 ulRc++;
1110 }
1111
1112
1113 /*
1114 * Authors
1115 */
1116 sprintf(pszQuery, "DELETE FROM fnauthor WHERE function = %ld", pFnDesc->alRefCode[k]);
1117 rc = mysql_queryu7(pmysql, pszQuery);
1118 if (rc < 0)
1119 {
1120 if (*pszError == ' ')
1121 strcpy(pszError++, "\n\t");
1122 sprintf(pszError, "Deleting old authors failed with error: %s - (sql=%s) ",
1123 dbGetLastErrorDesc(), pszQuery);
1124 pszError += strlen(pszError) - 1;
1125 ulRc++;
1126 }
1127
1128 for (i = 0; i < pFnDesc->cAuthors; i++)
1129 {
1130 if (pFnDesc->alAuthorRefCode[i] == -1)
1131 continue;
1132 sprintf(pszQuery, "INSERT INTO fnauthor(author, function) "
1133 "VALUES (%ld, %ld)",
1134 pFnDesc->alAuthorRefCode[i], pFnDesc->alRefCode[k]);
1135 rc = mysql_queryu8(pmysql, pszQuery);
1136 if (rc < 0)
1137 {
1138 if (*pszError == ' ')
1139 strcpy(pszError++, "\n\t");
1140 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
1141 i, dbGetLastErrorDesc(), pszQuery);
1142 pszError += strlen(pszError) - 1;
1143 ulRc++;
1144 }
1145 }
1146 } /* for */
1147
1148 lDll = lDll;
1149 free(pszQuery2);
1150 return ulRc;
1151}
1152
1153
1154/**
1155 * Removes all the existing design notes in the specified file.
1156 * @returns Success indicator.
1157 * @param lFile File refcode of the file to remove all design notes for.
1158 * @sketch
1159 * @status
1160 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1161 * @remark
1162 */
1163BOOL _System dbRemoveDesignNotes(signed long lFile)
1164{
1165 char szQuery[80];
1166
1167 assert(lFile >= 0);
1168 sprintf(&szQuery[0], "DELETE FROM designnote WHERE file = %ld", lFile);
1169 return mysql_query(pmysql, &szQuery[0]) >= 0;
1170}
1171
1172
1173/**
1174 * Adds a design note.
1175 * @returns Success indicator.
1176 * @param lDll Dll refcode.
1177 * @param lFile File refcode.
1178 * @param pszTitle Design note title.
1179 * @param pszText Design note text.
1180 * @param lSeqNbr Sequence number (in dll). If 0 the use next available number.
1181 * @param lSeqNbrFile Sequence number in file.
1182 */
1183BOOL _System dbAddDesignNote(signed long lDll,
1184 signed long lFile,
1185 const char *pszTitle,
1186 const char *pszText,
1187 signed long lSeqNbr,
1188 signed long lSeqNbrFile)
1189{
1190 char szQuery[0x10200];
1191 MYSQL_RES * pres;
1192
1193
1194 assert(lDll >= 0 && lFile >= 0);
1195 assert(lSeqNbrFile >= 0);
1196
1197 /*
1198 * If no lSqlNbr the make one.
1199 */
1200 if (lSeqNbr == 0)
1201 {
1202 sprintf(&szQuery[0], "SELECT MAX(lSeqNbr) + 1 FROM designnote WHERE dll = %ld'", lDll);
1203 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1204 {
1205 pres = mysql_store_result(pmysql);
1206 if (pres != NULL)
1207 {
1208 MYSQL_ROW parow = mysql_fetch_row(pres);
1209 if (parow != NULL)
1210 lSeqNbr = getvalue(0, parow);
1211 else
1212 lSeqNbr = 1;
1213 mysql_free_result(pres);
1214 }
1215 else
1216 return FALSE;
1217 }
1218 else
1219 return FALSE;
1220 }
1221
1222 /*
1223 * Create update query.
1224 */
1225 sprintf(&szQuery[0], "INSERT INTO designnote(dll, file, seqnbrfile, seqnbr, title, note) "
1226 "VALUES (%ld, %ld, %ld, %ld, ",
1227 lDll, lFile, lSeqNbrFile, lSeqNbr);
1228 if (pszTitle != NULL && *pszTitle != '\0')
1229 sqlstrcat(&szQuery[0], NULL, pszTitle);
1230 else
1231 strcat(&szQuery[0], "NULL");
1232 sqlstrcat(&szQuery[0], ", ", pszText == NULL ? "" : pszText, ")");
1233
1234 return mysql_query(pmysql, &szQuery[0]) >= 0;
1235}
1236
1237
1238
1239/**
1240 * Updates the history tables.
1241 * @returns Number of signals/errors.
1242 * @param pszError Pointer to buffer which will hold the error messages.
1243 * @remark This should be called whenever updates have been completed.
1244 */
1245unsigned long _System dbCreateHistory(char *pszError)
1246{
1247 unsigned long ulRc = 0;
1248 MYSQL_RES *pres;
1249 MYSQL_ROW row;
1250 char szQuery[256];
1251 char *pszQuery = &szQuery[0];
1252 int rc;
1253 char szCurDt[20] = {0}; /*yyyy-mm-dd\0*/
1254
1255 mysql_refresh(pmysql, REFRESH_TABLES);
1256
1257 /* get currentdate - just in case the date changes between the delete and the update is completed. */
1258 strcpy(pszQuery, "SELECT CURDATE()");
1259 rc = mysql_query(pmysql, pszQuery);
1260 pres = mysql_use_result(pmysql);
1261 if (rc >= 0 && pres != NULL)
1262 {
1263 row = mysql_fetch_row(pres);
1264 if (row != NULL && mysql_num_rows(pres) == 1)
1265 {
1266 strcpy(&szCurDt[0], row[0]);
1267 while (mysql_fetch_row(pres) != NULL)
1268 pres=pres;
1269
1270 /* delete - all rows on this date in the history tables */
1271 sprintf(pszQuery, "DELETE FROM historydll WHERE date = '%s'", &szCurDt[0]);
1272 rc = mysql_query(pmysql, pszQuery);
1273 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1274
1275 sprintf(pszQuery, "DELETE FROM historyapigroup WHERE date = '%s'", &szCurDt[0]);
1276 rc = mysql_query(pmysql, pszQuery);
1277 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1278
1279 sprintf(pszQuery, "DELETE FROM historydlltotal WHERE date = '%s'", &szCurDt[0]);
1280 rc = mysql_query(pmysql, pszQuery);
1281 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1282
1283 sprintf(pszQuery, "DELETE FROM historyapigrouptotal WHERE date = '%s'", &szCurDt[0]);
1284 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1285
1286 /* insert new stats */
1287 sprintf(pszQuery, "INSERT INTO historydll(dll, state, date, count) "
1288 "SELECT dll, state, '%s', count(*) FROM function GROUP BY dll, state",
1289 &szCurDt[0]);
1290 rc = mysql_query(pmysql, pszQuery);
1291 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1292
1293 sprintf(pszQuery, "INSERT INTO historyapigroup(apigroup, state, date, count) "
1294 "SELECT dll, state, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
1295 "GROUP BY apigroup, state",
1296 &szCurDt[0]);
1297 rc = mysql_query(pmysql, pszQuery);
1298 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1299
1300 /* inserting new totals */
1301 sprintf(pszQuery, "INSERT INTO historydlltotal(dll, date, totalcount) "
1302 "SELECT dll, '%s', count(*) FROM function GROUP BY dll",
1303 &szCurDt[0]);
1304 rc = mysql_query(pmysql, pszQuery);
1305 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1306
1307 sprintf(pszQuery, "INSERT INTO historyapigrouptotal(apigroup, date, totalcount) "
1308 "SELECT apigroup, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
1309 "GROUP BY apigroup",
1310 &szCurDt[0]);
1311 rc = mysql_query(pmysql, pszQuery);
1312 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1313 }
1314 else
1315 {
1316 sprintf(pszError, "error getting current date (row == NULL): %s - (sql=%s) ",
1317 dbGetLastErrorDesc(), pszQuery);
1318 ulRc++;
1319 }
1320 }
1321 else
1322 {
1323 sprintf(pszError, "error getting current date: %s - (sql=%s) ",
1324 dbGetLastErrorDesc(), pszQuery);
1325 ulRc++;
1326 }
1327
1328 mysql_refresh(pmysql, REFRESH_TABLES);
1329
1330 return ulRc;
1331}
1332
1333
1334/**
1335 * Check that database integrety is ok. Verfies foreign keys.
1336 * @returns numbers of errors.
1337 * @param pszError Very large buffer which will hold error messges (if any).
1338 * @sketch
1339 * @remark current versions of mysql don't support 'SELECT ... WHERE id NOT IN(SELECT id FROM table)'
1340 */
1341unsigned long _System dbCheckIntegrity(char *pszError)
1342{
1343 char szQuery[384];
1344 char *pszQuery = &szQuery[0];
1345 MYSQL_RES *pres1;
1346 MYSQL_RES *pres2;
1347 MYSQL_ROW row1;
1348 int rc;
1349 unsigned long ulRc = 0;
1350
1351 mysql_refresh(pmysql, REFRESH_TABLES);
1352
1353 /* foreign keys in function table */
1354 strcpy(pszQuery, "SELECT refcode, dll, state, apigroup, file FROM function");
1355 rc = mysql_query(pmysql, pszQuery);
1356 if (rc >= 0)
1357 {
1358 pres1 = mysql_store_result(pmysql);
1359 if (pres1 != NULL)
1360 {
1361 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1362 {
1363 /* check dll */
1364 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1365 rc = mysql_query(pmysql, pszQuery);
1366 CheckFKError("function/dll", "Foreign key 'dll' not found in the dll table");
1367
1368 /* check state */
1369 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1370 rc = mysql_query(pmysql, pszQuery);
1371 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1372
1373 /* check apigroup */
1374 if (row1[3] != NULL)
1375 {
1376 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[3]);
1377 rc = mysql_query(pmysql, pszQuery);
1378 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1379 }
1380
1381 /* check file */
1382 if (atoi(row1[4]) >= 0)
1383 {
1384 sprintf(pszQuery, "SELECT refcode FROM file WHERE refcode = %s", row1[4]);
1385 rc = mysql_query(pmysql, pszQuery);
1386 CheckFKError("function/file", "Foreign key 'file' not found in the file table");
1387 }
1388 }
1389 mysql_free_result(pres1);
1390 }
1391 }
1392 else
1393 ulRc += logDbError(pszError, pszQuery);
1394
1395 /* foreign keys in file */
1396 strcpy(pszQuery, "SELECT refcode, dll FROM file");
1397 rc = mysql_query(pmysql, pszQuery);
1398 if (rc >= 0)
1399 {
1400 pres1 = mysql_store_result(pmysql);
1401 if (pres1 != NULL)
1402 {
1403 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1404 {
1405 /* check dll */
1406 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1407 rc = mysql_query(pmysql, pszQuery);
1408 CheckFKError("apigroup/dll", "Foreign key 'dll' not found in the dll table");
1409 }
1410 mysql_free_result(pres1);
1411 }
1412 }
1413 else
1414 ulRc += logDbError(pszError, pszQuery);
1415
1416 /* foreign keys in apigroup */
1417 strcpy(pszQuery, "SELECT refcode, dll FROM apigroup");
1418 rc = mysql_query(pmysql, pszQuery);
1419 if (rc >= 0)
1420 {
1421 pres1 = mysql_store_result(pmysql);
1422 if (pres1 != NULL)
1423 {
1424 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1425 {
1426 /* check dll */
1427 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1428 rc = mysql_query(pmysql, pszQuery);
1429 CheckFKError("file/dll", "Foreign key 'dll' not found in the dll table");
1430 }
1431 mysql_free_result(pres1);
1432 }
1433 }
1434 else
1435 ulRc += logDbError(pszError, pszQuery);
1436
1437 /* foreign keys in fnauthor */
1438 strcpy(pszQuery, "SELECT function, author FROM fnauthor");
1439 rc = mysql_query(pmysql, pszQuery);
1440 if (rc >= 0)
1441 {
1442 pres1 = mysql_store_result(pmysql);
1443 if (pres1 != NULL)
1444 {
1445 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1446 {
1447 /* check function */
1448 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1449 rc = mysql_query(pmysql, pszQuery);
1450 CheckFKError("fnauthor/function", "Foreign key 'function' not found in the function table");
1451
1452 /* check author */
1453 sprintf(pszQuery, "SELECT refcode FROM author WHERE refcode = %s", row1[1]);
1454 rc = mysql_query(pmysql, pszQuery);
1455 CheckFKError("fnauthor/author", "Foreign key 'author' not found in the author table");
1456 }
1457 mysql_free_result(pres1);
1458 }
1459 }
1460 else
1461 ulRc += logDbError(pszError, pszQuery);
1462
1463 /* foreign keys in historydll table */
1464 strcpy(pszQuery, "SELECT date, dll, state FROM historydll");
1465 rc = mysql_query(pmysql, pszQuery);
1466 if (rc >= 0)
1467 {
1468 pres1 = mysql_store_result(pmysql);
1469 if (pres1 != NULL)
1470 {
1471 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1472 {
1473 /* check dll */
1474 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1475 rc = mysql_query(pmysql, pszQuery);
1476 CheckFKError("historydll/dll", "Foreign key 'dll' not found in the dll table");
1477
1478 /* check state */
1479 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1480 rc = mysql_query(pmysql, pszQuery);
1481 CheckFKError("historydll/state", "Foreign key 'state' not found in the state table");
1482 }
1483 mysql_free_result(pres1);
1484 }
1485 }
1486 else
1487 ulRc += logDbError(pszError, pszQuery);
1488
1489 /* foreign keys in historyapigroup table */
1490 strcpy(pszQuery, "SELECT date, apigroup, state FROM historyapigroup");
1491 rc = mysql_query(pmysql, pszQuery);
1492 if (rc >= 0)
1493 {
1494 pres1 = mysql_store_result(pmysql);
1495 if (pres1 != NULL)
1496 {
1497 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1498 {
1499 /* check dll */
1500 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1501 rc = mysql_query(pmysql, pszQuery);
1502 CheckFKError("historyapigroup/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1503
1504 /* check state */
1505 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1506 rc = mysql_query(pmysql, pszQuery);
1507 CheckFKError("historyapigroup/state", "Foreign key 'state' not found in the state table");
1508 }
1509 mysql_free_result(pres1);
1510 }
1511 }
1512 else
1513 ulRc += logDbError(pszError, pszQuery);
1514
1515 /* foreign keys in historydlltotal table */
1516 strcpy(pszQuery, "SELECT date, dll FROM historydlltotal");
1517 rc = mysql_query(pmysql, pszQuery);
1518 if (rc >= 0)
1519 {
1520 pres1 = mysql_store_result(pmysql);
1521 if (pres1 != NULL)
1522 {
1523 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1524 {
1525 /* check dll */
1526 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1527 rc = mysql_query(pmysql, pszQuery);
1528 CheckFKError("historydlltotal/dll", "Foreign key 'dll' not found in the dll table");
1529 }
1530 mysql_free_result(pres1);
1531 }
1532 }
1533 else
1534 ulRc += logDbError(pszError, pszQuery);
1535
1536 /* foreign keys in historyapigroup table */
1537 strcpy(pszQuery, "SELECT date, apigroup FROM historyapigrouptotal");
1538 rc = mysql_query(pmysql, pszQuery);
1539 if (rc >= 0)
1540 {
1541 pres1 = mysql_store_result(pmysql);
1542 if (pres1 != NULL)
1543 {
1544 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1545 {
1546 /* check dll */
1547 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1548 rc = mysql_query(pmysql, pszQuery);
1549 CheckFKError("historyapigrouptotal/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1550 }
1551 mysql_free_result(pres1);
1552 }
1553 }
1554 else
1555 ulRc += logDbError(pszError, pszQuery);
1556
1557 /* foreign keys in parameter table */
1558 strcpy(pszQuery, "SELECT sequencenbr, function FROM parameter");
1559 rc = mysql_query(pmysql, pszQuery);
1560 if (rc >= 0)
1561 {
1562 pres1 = mysql_store_result(pmysql);
1563 if (pres1 != NULL)
1564 {
1565 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1566 {
1567 /* check function */
1568 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1569 rc = mysql_query(pmysql, pszQuery);
1570 CheckFKError("parameter/function", "Foreign key 'function' not found in the function table");
1571 }
1572 mysql_free_result(pres1);
1573 }
1574 }
1575 else
1576 ulRc += logDbError(pszError, pszQuery);
1577
1578 /* Author table is special, since you should be able to interchangably reference an
1579 * author by any of the following tables:
1580 * name
1581 * initials
1582 * alias
1583 * email
1584 */
1585 strcpy(pszQuery, "SELECT name, initials, alias, email FROM author");
1586 rc = mysql_query(pmysql, pszQuery);
1587 if (rc >= 0)
1588 {
1589 pres1 = mysql_store_result(pmysql);
1590 if (pres1 != NULL)
1591 {
1592 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1593 {
1594 /* check name */
1595 sprintf(pszQuery, "SELECT name FROM author WHERE "
1596 "initials = '%s' OR alias = '%s' OR email = '%s'",
1597 row1[0], row1[0], row1[0]);
1598 ulRc += CheckAuthorError(pszError, "name", row1[0], pszQuery);
1599
1600 /* check initials */
1601 sprintf(pszQuery, "SELECT name FROM author WHERE "
1602 "alias = '%s' OR email = '%s'",
1603 row1[1], row1[1]);
1604 ulRc += CheckAuthorError(pszError, "initials", row1[1], pszQuery);
1605
1606 /* alias */
1607 if (row1[2] != NULL)
1608 {
1609 sprintf(pszQuery, "SELECT name FROM author WHERE "
1610 "email = '%s'",
1611 row1[2]);
1612 ulRc += CheckAuthorError(pszError, "alias", row1[2], pszQuery);
1613 }
1614 }
1615 mysql_free_result(pres1);
1616 }
1617 }
1618 else
1619 ulRc += logDbError(pszError, pszQuery);
1620
1621 return ulRc;
1622}
1623
1624
1625/**
1626 * Checks for duplicate key and sql error for a given author key in the author table... (arg!)
1627 * @returns Number of errors.
1628 * @param pszError Reference to error buffer pointer.
1629 * @param pszFieldName Key field name; used for logging.
1630 * @param pszFieldValue Key value; used for logging
1631 * @param pszQuery Query which is to be exectued to test for duplicate key.
1632 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1633 */
1634static unsigned long CheckAuthorError(char * &pszError, const char *pszFieldName, const char *pszFieldValue, const char *pszQuery)
1635{
1636 MYSQL_ROW row;
1637 MYSQL_RES *pres;
1638 unsigned long ulRc = 0;
1639 int rc;
1640
1641 rc = mysql_query(pmysql, pszQuery);
1642 pres = mysql_store_result(pmysql);
1643 if (rc < 0 || (pres != NULL && mysql_num_rows(pres) != 0))
1644 { /* some kind of error has occurred */
1645 if (pszError[1] == '\xFE')
1646 {
1647 strcat(pszError, "\n\t");
1648 pszError += 2;
1649 }
1650
1651 if (rc < 0) /* sql error or 'duplicate key' */
1652 {
1653 sprintf(pszError, "author/%s: select failed - %s (sql=%s)",
1654 pszFieldName, dbGetLastErrorDesc(), pszQuery);
1655 }
1656 else
1657 { /* 'duplicate key' - print duplicates */
1658 sprintf(pszError, "author/%s: 'duplicate key', %s='%s': ",
1659 pszFieldName, pszFieldValue, pszFieldName);
1660
1661 while ((row = mysql_fetch_row(pres)) != NULL)
1662 {
1663 pszError += strlen(pszError);
1664 sprintf(pszError, "'%s' ", row[0]);
1665 }
1666 }
1667
1668 pszError += strlen(pszError);
1669 pszError[1] = '\xFE';
1670 ulRc = 1;
1671 }
1672 if (pres != NULL)
1673 mysql_free_result(pres);
1674
1675 return ulRc;
1676}
1677
1678
1679/**
1680 * Writes db error (rc<0) to the log buffer.
1681 * @returns Number of signals.
1682 * @param pszError Reference to the error buffer pointer.
1683 * @param pszQuery Pointer to query which was executed.
1684 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1685 */
1686static unsigned long logDbError(char * &pszError, const char *pszQuery)
1687{
1688 if (pszError[1] == '\xFE')
1689 {
1690 strcat(pszError, "\n\t");
1691 pszError += 2;
1692 }
1693 sprintf(pszError, "select failed: %s - (sql=%s)", dbGetLastErrorDesc(), pszQuery);
1694
1695 pszError += strlen(pszError);
1696 pszError[1] = '\xFE';
1697
1698 return 1;
1699}
1700
1701
1702/**
1703 * Executes a give query and returns a result identifier/pointer.
1704 * @returns Query result identifier/pointer. NULL on error.
1705 * @param pszQuery Pointer to query.
1706 * @remark Used by and designed for kHtmlPC.
1707 */
1708void * _System dbExecuteQuery(const char *pszQuery)
1709{
1710 assert(pmysql != NULL);
1711 if (mysql_query(pmysql, pszQuery) >= 0)
1712 return mysql_store_result(pmysql);
1713
1714 return NULL;
1715}
1716
1717
1718/**
1719 * Asks for the number of rows in the result.
1720 * @returns Number of rows in the result. -1 on error.
1721 * @param pres Query result identifier/pointer.
1722 * @remark Used by and designed for kHtmlPC.
1723 */
1724signed long _System dbQueryResultRows(void *pres)
1725{
1726 if (pres == NULL)
1727 return -1;
1728 return mysql_num_rows((MYSQL_RES*)pres);
1729}
1730
1731
1732/**
1733 * Frees the storage allocated by the given result.
1734 * @returns Success indicator, TRUE/FALSE.
1735 * @param pres Query result identifier/pointer.
1736 * @remark Used by and designed for kHtmlPC.
1737 */
1738BOOL _System dbFreeResult(void *pres)
1739{
1740 if (pres != NULL)
1741 mysql_free_result((MYSQL_RES*)pres);
1742 else
1743 return FALSE;
1744 return TRUE;
1745}
1746
1747
1748/**
1749 * Fetch data from a result. Returns the data by calling the given callback function.
1750 * @returns Success indicator, TRUE/FALSE.
1751 * @param pres Query result identifier/pointer.
1752 * @param dbFetchCallBack Callback-function.
1753 * @param pvUser User parameter which is passed onto dbFetchCallBack.
1754 * @remark Used by and designed for kHtmlPC.
1755 */
1756BOOL _System dbFetch(void *pres, DBCALLBACKFETCH dbFetchCallBack, void *pvUser)
1757{
1758 BOOL fRc = FALSE;
1759 MYSQL_ROW row = mysql_fetch_row((MYSQL_RES*)pres);
1760
1761 if (row)
1762 {
1763 MYSQL_FIELD *pField;
1764 int i = 0;
1765 mysql_field_seek((MYSQL_RES*)pres, 0);
1766
1767 while ((pField = mysql_fetch_field((MYSQL_RES*)pres)) != NULL)
1768 if (dbFetchCallBack(row[i++], pField->name, pvUser) != 0)
1769 return FALSE;
1770
1771 fRc = TRUE;
1772 }
1773
1774 return fRc;
1775}
1776
1777
1778/**
1779 * Converts an ISO date to days after Christ, year 0.
1780 * @returns days. -1 on error;
1781 * @param pszDate ISO Date.
1782 */
1783signed long _System dbDateToDaysAfterChrist(const char *pszDate)
1784{
1785 signed long lRet = -1;
1786 char szQuery[128];
1787
1788 sprintf(&szQuery[0], "SELECT to_days('%s')", pszDate);
1789 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1790 {
1791 MYSQL_ROW row;
1792 MYSQL_RES *pres = mysql_use_result(pmysql);
1793 row = mysql_fetch_row(pres);
1794 if (row != NULL)
1795 {
1796 lRet = atol(row[0]);
1797 do { row = mysql_fetch_row(pres); } while (row != NULL);
1798 }
1799 }
1800
1801 return lRet;
1802}
1803
1804
1805/**
1806 * Converts days after Christ (year 0) to ISO date.
1807 * @returns Success indicator. TRUE/FALSE;
1808 * @param lDays Days after Christ (year 0).
1809 * @param pszDate ISO Date. Result.
1810 */
1811BOOL _System dbDaysAfterChristToDate(signed long lDays, char *pszDate)
1812{
1813 BOOL fRet = FALSE;
1814 char szQuery[128];
1815
1816 if (lDays < 0)
1817 return FALSE;
1818
1819 sprintf(&szQuery[0], "SELECT from_days(%ld)", lDays);
1820 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1821 {
1822 MYSQL_ROW row;
1823 MYSQL_RES *pres = mysql_use_result(pmysql);
1824 row = mysql_fetch_row(pres);
1825 if (row != NULL)
1826 {
1827 fRet = strlen(row[0]) == (4+1+2+1+2) && row[0][4] == '-' && row[0][7] == '-'
1828 && strcmp(row[0], "0000-00-00") != 0;
1829 if (fRet)
1830 strcpy(pszDate, row[0]);
1831 do { row = mysql_fetch_row(pres); } while (row != NULL);
1832 }
1833 }
1834
1835 return fRet;
1836}
1837
1838
1839/**
1840 * Display all functions for, the given dll, that is not updated.
1841 * @returns TRUE / FALSE.
1842 * @param lDll Dll reference number.
1843 * @param dbFetchCall Callback function which will be called once for each
1844 * field for all the functions not updated.
1845 * pvUser is NULL, pszValue field value, pszFieldName the field name.
1846 */
1847BOOL _System dbGetNotUpdatedFunction(signed long lDll, DBCALLBACKFETCH dbFetchCallBack)
1848{
1849 BOOL fRet = FALSE;
1850 void *pres;
1851 char szQuery[256];
1852
1853 /* not updated names */
1854 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1855 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1856 " LEFT JOIN dll d ON f2.dll = d.refcode "
1857 "WHERE f1.dll = %ld AND f1.updated = 0",
1858 lDll);
1859 pres = dbExecuteQuery(szQuery);
1860 if (pres != NULL)
1861 {
1862 BOOL f;
1863 do
1864 {
1865 f = dbFetch(pres, dbFetchCallBack, NULL);
1866 } while (f);
1867 dbFreeResult(pres);
1868 fRet = TRUE;
1869 }
1870
1871 /* warn about updated > 1 too */
1872 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1873 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1874 " LEFT JOIN dll d ON f2.dll = d.refcode "
1875 "WHERE f1.dll = %ld AND f1.updated > 1",
1876 lDll);
1877 pres = dbExecuteQuery(szQuery);
1878 if (pres != NULL)
1879 {
1880 BOOL f;
1881 do
1882 {
1883 f = dbFetch(pres, dbFetchCallBack, NULL);
1884 } while (f);
1885 dbFreeResult(pres);
1886 fRet = TRUE;
1887 }
1888
1889 strcpy(&szQuery[0], "UPDATE function SET updated = 0");
1890 mysql_query(pmysql, &szQuery[0]);
1891
1892 return fRet;
1893}
1894
1895
1896/**
1897 * Counts the function for the given DLL which has been updated.
1898 * @returns -1 on error, number of updated function on success.
1899 * @param lDll Dll reference number.
1900 */
1901signed long _System dbGetNumberOfUpdatedFunction(signed long lDll)
1902{
1903 int rc;
1904 char szQuery[128];
1905 MYSQL_RES * pres;
1906
1907 sprintf(&szQuery[0], "SELECT count(*) FROM function WHERE dll = (%ld) AND updated > 0\n", lDll);
1908 rc = mysql_query(pmysql, &szQuery[0]);
1909 pres = mysql_store_result(pmysql);
1910 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
1911 rc = (int)getvalue(0, mysql_fetch_row(pres));
1912 else
1913 rc = -1;
1914 mysql_free_result(pres);
1915 return (signed long)rc;
1916}
1917
1918
1919/**
1920 * Appends a set of strings to a query. The main string (pszStr) is enclosed in "'"s.
1921 * @returns Pointer to end of the string.
1922 * @param pszQuery Outputbuffer
1923 * @param pszBefore Text before string, might be NULL.
1924 * @param pszStr String (NOT NULL)
1925 * @param pszAfter Text after, might be NULL.
1926 * @status completely implemented
1927 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1928 */
1929static char *sqlstrcat(char *pszQuery, const char *pszBefore, const char *pszStr, const char *pszAfter)
1930{
1931 register char ch;
1932
1933 pszQuery += strlen(pszQuery);
1934
1935 /*
1936 * String before
1937 */
1938 if (pszBefore != NULL)
1939 {
1940 strcpy(pszQuery, pszBefore);
1941 pszQuery += strlen(pszQuery);
1942 }
1943
1944 /*
1945 * THE String
1946 */
1947 *pszQuery++ = '\'';
1948 while ((ch = *pszStr++) != '\0')
1949 {
1950 if (ch == '\'')
1951 {
1952 *pszQuery++ = '\\';
1953 *pszQuery++ = '\'';
1954 }
1955 else if (ch == '\n')
1956 {
1957 #if 0
1958 *pszQuery++ = '\\';
1959 *pszQuery++ = 'n';
1960 #else
1961 *pszQuery++ = '<';
1962 *pszQuery++ = 'B';
1963 *pszQuery++ = 'R';
1964 *pszQuery++ = '>';
1965 #endif
1966 }
1967 else if (ch == '\r')
1968 {
1969 #if 0
1970 *pszQuery++ = '\\';
1971 *pszQuery++ = 'r';
1972 #else
1973 *pszQuery++ = '<';
1974 *pszQuery++ = 'B';
1975 *pszQuery++ = 'R';
1976 *pszQuery++ = '>';
1977 #endif
1978 }
1979 else
1980 *pszQuery++ = ch;
1981 }
1982 *pszQuery++ = '\'';
1983
1984 /*
1985 * String after
1986 */
1987 if (pszAfter != NULL)
1988 {
1989 strcpy(pszQuery, pszAfter);
1990 pszQuery += strlen(pszQuery);
1991 }
1992 else
1993 *pszQuery = '\0';
1994
1995
1996 return pszQuery;
1997}
1998
1999
2000#ifndef DLL
2001/**
2002 * Signal handler.
2003 * Ensures that the database connection is closed at termination.
2004 * @param sig Signal number.
2005 */
2006void dbHandler(int sig)
2007{
2008 if (pmysql != NULL)
2009 {
2010 fprintf(stderr, "\n\t!disconnecting from database!\n");
2011 dbDisconnect();
2012 }
2013
2014 flushall();
2015 switch (sig)
2016 {
2017 case SIGBREAK:
2018 printf("\nSIGBREAK\n");
2019 exit(-1);
2020 break;
2021 case SIGINT:
2022 printf("\nSIGINT\n");
2023 exit(-1);
2024 break;
2025 case SIGTERM:
2026 printf("\nSIGTERM\n");
2027 exit(-1);
2028 break;
2029 case SIGSEGV:
2030 raise(sig);
2031 break;
2032 case SIGILL:
2033 printf("\nSIGILL\n");
2034 exit(-1);
2035 break;
2036 }
2037}
2038
2039
2040#else
2041/*******/
2042/* DLL */
2043/*******/
2044/* prototypes used in the _DLL_InitTerm function */
2045extern "C"
2046{
2047 int _CRT_init(void);
2048 void _CRT_term(void);
2049 void __ctordtorInit( void );
2050 void __ctordtorTerm( void );
2051 unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag);
2052}
2053
2054
2055/**
2056 * Dll InitTerm function.
2057 * @returns 0 on success.
2058 * 1 on error.
2059 * @param hModule
2060 * @param ulFlags
2061 * @remark We'll ensure that the database connection is terminated as we terminate.
2062 */
2063unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag)
2064{
2065 /*-------------------------------------------------------------------------*/
2066 /* If ulFlag is zero then the DLL is being loaded so initialization should */
2067 /* be performed. If ulFlag is 1 then the DLL is being freed so */
2068 /* termination should be performed. */
2069 /*-------------------------------------------------------------------------*/
2070
2071 switch (ulFlag)
2072 {
2073 case 0:
2074 if (_CRT_init() == -1)
2075 return 0;
2076 __ctordtorInit();
2077 break;
2078
2079 case 1:
2080 /* ensure that db connection is terminated */
2081 if (pmysql != NULL)
2082 {
2083 fprintf(stderr, "\n\t!disconnecting from database!\n");
2084 dbDisconnect();
2085 }
2086 __ctordtorTerm();
2087 break;
2088
2089 default:
2090 return 0;
2091 }
2092 hModule = hModule;
2093 return 1;
2094}
2095
2096/*****************************************************************/
2097/* -why is this terminate function referenced but not defined??? */
2098/* and where is it referenced??? */
2099/* -Probably an export missing from the libraries. */
2100/*****************************************************************/
2101void terminate(void)
2102{
2103 DosPutMessage(0, sizeof("terminate")-1, "terminate");
2104 exit(-1);
2105}
2106
2107/****************************************/
2108/* EMX run-time trouble */
2109/* _environ is missing when using -Zomf */
2110/****************************************/
2111char **_environ = environ;
2112
2113#endif
Note: See TracBrowser for help on using the repository browser.