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

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

Added line numbers for function and designnote.
Corrected reading of SDS function headers.

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