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

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

Added and updated authors.
Corrected dep rule in makefile
Corrections and improvements in stateupd.

File size: 71.4 KB
Line 
1/* $Id: db.cpp,v 1.15 2000-07-18 17:56:50 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 assert(parow);
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 char * pszLineStart = pszQuery;
1932 register char ch;
1933
1934 pszQuery += strlen(pszQuery);
1935
1936 /*
1937 * String before
1938 */
1939 if (pszBefore != NULL)
1940 {
1941 strcpy(pszQuery, pszBefore);
1942 pszQuery += strlen(pszQuery);
1943 }
1944
1945 /*
1946 * THE String
1947 */
1948 *pszQuery++ = '\'';
1949 while ((ch = *pszStr++) != '\0')
1950 {
1951 switch (ch)
1952 {
1953 case '\'':
1954 *pszQuery++ = '\\';
1955 *pszQuery++ = '\'';
1956 break;
1957
1958 case '"':
1959 *pszQuery++ = '\\';
1960 *pszQuery++ = '"';
1961 break;
1962
1963 case '\\':
1964 *pszQuery++ = '\\';
1965 *pszQuery++ = '\\';
1966 break;
1967
1968 case '%':
1969 *pszQuery++ = '\\';
1970 *pszQuery++ = '%';
1971 break;
1972
1973 case '_':
1974 *pszQuery++ = '\\';
1975 *pszQuery++ = '_';
1976 break;
1977
1978 case '\n':
1979 *pszQuery++ = '\\';
1980 *pszQuery++ = 'r';
1981 *pszQuery++ = '\\';
1982 *pszQuery++ = 'n';
1983 break;
1984
1985 case '\t':
1986 *pszQuery++ = '\\';
1987 *pszQuery++ = 't';
1988 break;
1989
1990 case '\r':
1991 break;
1992
1993 default:
1994 *pszQuery++ = ch;
1995 }
1996
1997 /* Add new lines every 80 chars MySql don't like long lines. */
1998 if (pszLineStart - pszQuery > 80)
1999 {
2000 *pszQuery = '\n';
2001 pszLineStart = pszQuery;
2002 }
2003 }
2004 *pszQuery++ = '\'';
2005
2006 /*
2007 * String after
2008 */
2009 if (pszAfter != NULL)
2010 {
2011 strcpy(pszQuery, pszAfter);
2012 pszQuery += strlen(pszQuery);
2013 }
2014 else
2015 *pszQuery = '\0';
2016
2017
2018 return pszQuery;
2019}
2020
2021
2022#ifndef DLL
2023/**
2024 * Signal handler.
2025 * Ensures that the database connection is closed at termination.
2026 * @param sig Signal number.
2027 */
2028void dbHandler(int sig)
2029{
2030 if (pmysql != NULL)
2031 {
2032 fprintf(stderr, "\n\t!disconnecting from database!\n");
2033 dbDisconnect();
2034 }
2035
2036 flushall();
2037 switch (sig)
2038 {
2039 case SIGBREAK:
2040 printf("\nSIGBREAK\n");
2041 exit(-1);
2042 break;
2043 case SIGINT:
2044 printf("\nSIGINT\n");
2045 exit(-1);
2046 break;
2047 case SIGTERM:
2048 printf("\nSIGTERM\n");
2049 exit(-1);
2050 break;
2051 case SIGSEGV:
2052 raise(sig);
2053 break;
2054 case SIGILL:
2055 printf("\nSIGILL\n");
2056 exit(-1);
2057 break;
2058 }
2059}
2060
2061
2062#else
2063/*******/
2064/* DLL */
2065/*******/
2066/* prototypes used in the _DLL_InitTerm function */
2067extern "C"
2068{
2069 int _CRT_init(void);
2070 void _CRT_term(void);
2071 void __ctordtorInit( void );
2072 void __ctordtorTerm( void );
2073 unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag);
2074}
2075
2076
2077/**
2078 * Dll InitTerm function.
2079 * @returns 0 on success.
2080 * 1 on error.
2081 * @param hModule
2082 * @param ulFlags
2083 * @remark We'll ensure that the database connection is terminated as we terminate.
2084 */
2085unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag)
2086{
2087 /*-------------------------------------------------------------------------*/
2088 /* If ulFlag is zero then the DLL is being loaded so initialization should */
2089 /* be performed. If ulFlag is 1 then the DLL is being freed so */
2090 /* termination should be performed. */
2091 /*-------------------------------------------------------------------------*/
2092
2093 switch (ulFlag)
2094 {
2095 case 0:
2096 if (_CRT_init() == -1)
2097 return 0;
2098 __ctordtorInit();
2099 break;
2100
2101 case 1:
2102 /* ensure that db connection is terminated */
2103 if (pmysql != NULL)
2104 {
2105 fprintf(stderr, "\n\t!disconnecting from database!\n");
2106 dbDisconnect();
2107 }
2108 __ctordtorTerm();
2109 break;
2110
2111 default:
2112 return 0;
2113 }
2114 hModule = hModule;
2115 return 1;
2116}
2117
2118/*****************************************************************/
2119/* -why is this terminate function referenced but not defined??? */
2120/* and where is it referenced??? */
2121/* -Probably an export missing from the libraries. */
2122/*****************************************************************/
2123void terminate(void)
2124{
2125 DosPutMessage(0, sizeof("terminate")-1, "terminate");
2126 exit(-1);
2127}
2128
2129/****************************************/
2130/* EMX run-time trouble */
2131/* _environ is missing when using -Zomf */
2132/****************************************/
2133char **_environ = environ;
2134
2135#endif
Note: See TracBrowser for help on using the repository browser.