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

Last change on this file since 8706 was 8006, checked in by bird, 24 years ago

New kFile* classes; now in sync with os2tools.

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