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

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

Design note improovments.

File size: 78.3 KB
Line 
1/* $Id: db.cpp,v 1.25 2001-09-06 03:07:32 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 "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, lastauthor, description, 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 0 /* keep getting duplicate keys when parameter order/names are changed. */
1018 if (atol(row[0]) == pFnDesc->cParams)
1019 { /* update parameters */
1020 for (i = 0; i < pFnDesc->cParams; i++)
1021 {
1022 sprintf(pszQuery, "UPDATE parameter SET type = '%s', name = '%s'",
1023 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
1024 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : "");
1025 if (pFnDesc->apszParamDesc[i] != NULL)
1026 sqlstrcat(pszQuery, ", description = ", pFnDesc->apszParamDesc[i]);
1027 sprintf(pszQuery + strlen(pszQuery), " WHERE function = (%ld) AND sequencenbr = (%ld)",
1028 pFnDesc->alRefCode[k], i);
1029 rc = mysql_queryu4(pmysql, pszQuery);
1030 if (rc < 0)
1031 {
1032 if (*pszError == ' ')
1033 strcpy(pszError++, "\n\t");
1034 sprintf(pszError, "Updating parameter %i failed with error: %s - (sql=%s) ",
1035 i, dbGetLastErrorDesc(), pszQuery);
1036 pszError += strlen(pszError) - 1;
1037 ulRc++;
1038 }
1039 }
1040 }
1041 else
1042 #endif
1043 {
1044 if (atol(row[0]) != 0)
1045 { /* delete old parameters */
1046 sprintf(pszQuery, "DELETE FROM parameter WHERE function = %ld", pFnDesc->alRefCode[k]);
1047 rc = mysql_queryu5(pmysql, pszQuery);
1048 if (rc < 0)
1049 {
1050 if (*pszError == ' ')
1051 strcpy(pszError++, "\n\t");
1052 sprintf(pszError, "Deleting old parameters failed with error: %s - (sql=%s) ",
1053 dbGetLastErrorDesc(), pszQuery);
1054 pszError += strlen(pszError) - 1;
1055 ulRc++;
1056 }
1057 }
1058
1059 /* insert parameters */
1060 for (i = 0; i < pFnDesc->cParams; i++)
1061 {
1062 sprintf(pszQuery, "INSERT INTO parameter(function, sequencenbr, type, name, description) "
1063 "VALUES (%ld, %d, '%s', '%s'",
1064 pFnDesc->alRefCode[k], i,
1065 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
1066 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : ""
1067 );
1068 if (pFnDesc->apszParamDesc[i] != NULL)
1069 sqlstrcat(pszQuery, ", ", pFnDesc->apszParamDesc[i], ")");
1070 else
1071 strcat(pszQuery, ", NULL)");
1072
1073 rc = mysql_queryu6(pmysql, pszQuery2);
1074 if (rc < 0)
1075 {
1076 if (*pszError == ' ')
1077 strcpy(pszError++, "\n\t");
1078 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
1079 i, dbGetLastErrorDesc(), pszQuery);
1080 pszError += strlen(pszError) - 1;
1081 ulRc++;
1082 }
1083 }
1084 }
1085 }
1086 else
1087 {
1088 if (*pszError == ' ')
1089 strcpy(pszError++, "\n\t");
1090 sprintf(pszError, "failed to store result or to fetch a row , error: %s - (sql=%s) ",
1091 dbGetLastErrorDesc(), pszQuery);
1092 pszError += strlen(pszError) - 1;
1093 ulRc++;
1094 }
1095 }
1096 else
1097 {
1098 if (*pszError == ' ')
1099 strcpy(pszError++, "\n\t");
1100 sprintf(pszError, "Failed querying number of parameters, error: %s - (sql=%s) ",
1101 dbGetLastErrorDesc(), pszQuery);
1102 pszError += strlen(pszError) - 1;
1103 ulRc++;
1104 }
1105
1106
1107 /*
1108 * Authors
1109 */
1110 sprintf(pszQuery, "DELETE FROM fnauthor WHERE function = %ld", pFnDesc->alRefCode[k]);
1111 rc = mysql_queryu7(pmysql, pszQuery);
1112 if (rc < 0)
1113 {
1114 if (*pszError == ' ')
1115 strcpy(pszError++, "\n\t");
1116 sprintf(pszError, "Deleting old authors failed with error: %s - (sql=%s) ",
1117 dbGetLastErrorDesc(), pszQuery);
1118 pszError += strlen(pszError) - 1;
1119 ulRc++;
1120 }
1121
1122 for (i = 0; i < pFnDesc->cAuthors; i++)
1123 {
1124 if (pFnDesc->alAuthorRefCode[i] == -1)
1125 continue;
1126 sprintf(pszQuery, "INSERT INTO fnauthor(author, function) "
1127 "VALUES (%ld, %ld)",
1128 pFnDesc->alAuthorRefCode[i], pFnDesc->alRefCode[k]);
1129 rc = mysql_queryu8(pmysql, pszQuery);
1130 if (rc < 0)
1131 {
1132 if (*pszError == ' ')
1133 strcpy(pszError++, "\n\t");
1134 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
1135 i, dbGetLastErrorDesc(), pszQuery);
1136 pszError += strlen(pszError) - 1;
1137 ulRc++;
1138 }
1139 }
1140 } /* for */
1141
1142 lDll = lDll;
1143 free(pszQuery2);
1144 return ulRc;
1145}
1146
1147
1148/**
1149 * Removes all the existing design notes in the specified file.
1150 * @returns Success indicator.
1151 * @param lFile File refcode of the file to remove all design notes for.
1152 * @sketch
1153 * @status
1154 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1155 * @remark
1156 */
1157BOOL _System dbRemoveDesignNotes(signed long lFile)
1158{
1159 char szQuery[80];
1160
1161 assert(lFile >= 0);
1162 sprintf(&szQuery[0], "DELETE FROM designnote WHERE file = %ld", lFile);
1163 return mysql_query(pmysql, &szQuery[0]) >= 0;
1164}
1165
1166
1167/**
1168 * Adds a design note.
1169 * @returns Success indicator.
1170 * @param lDll Dll refcode.
1171 * @param lFile File refcode.
1172 * @param pszTitle Design note title.
1173 * @param pszText Design note text.
1174 * @param lLevel Level of the note section. 0 is the design note it self.
1175 * @param lSeqNbr Sequence number (in dll). If 0 the use next available number.
1176 * @param lSeqNbrNote Sequence number in note.
1177 * @param lLine Line number (1 - based!).
1178 * @param fSubSection TRUE if subsection FALSE if design note.
1179 * if TRUE *plRefCode will hold the reference id of the note.
1180 * if FALSE *plRefCode will receive the reference id of the note being created.
1181 * @param plRefCode Pointer to reference id of the design note. see fSubSection for more info.
1182 */
1183BOOL _System dbAddDesignNote(signed long lDll,
1184 signed long lFile,
1185 const char *pszTitle,
1186 const char *pszText,
1187 signed long lLevel,
1188 signed long lSeqNbr,
1189 signed long lSeqNbrNote,
1190 signed long lLine,
1191 BOOL fSubSection,
1192 signed long *plRefCode)
1193{
1194 int rc;
1195 char szQuery[0x10200];
1196 MYSQL_RES * pres;
1197
1198
1199 assert(lDll >= 0 && lFile >= 0);
1200 assert(lSeqNbrNote >= 0);
1201
1202 /*
1203 * If no lSqlNbr the make one.
1204 */
1205 if (lSeqNbr == 0 && !fSubSection)
1206 {
1207 sprintf(&szQuery[0], "SELECT MAX(seqnbr) + 1 FROM designnote WHERE dll = %ld AND level = 0", lDll);
1208 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1209 {
1210 pres = mysql_store_result(pmysql);
1211 if (pres != NULL)
1212 {
1213 MYSQL_ROW parow = mysql_fetch_row(pres);
1214 if (parow != NULL && parow[0])
1215 lSeqNbr = getvalue(0, parow);
1216 else
1217 lSeqNbr = 1;
1218 mysql_free_result(pres);
1219 }
1220 else
1221 return FALSE;
1222 }
1223 else
1224 return FALSE;
1225 }
1226
1227 /*
1228 * Create insert query.
1229 */
1230 if (!fSubSection)
1231 sprintf(&szQuery[0], "INSERT INTO designnote(dll, file, level, seqnbrnote, seqnbr, line, name, note) "
1232 "VALUES (%ld, %ld, %ld, %ld, %ld, %ld, ",
1233 lDll, lFile, lLevel, lSeqNbrNote, lSeqNbr, lLine);
1234 else
1235 sprintf(&szQuery[0], "INSERT INTO designnote(refcode, dll, file, level, seqnbrnote, seqnbr, line, name, note) "
1236 "VALUES (%ld, %ld, %ld, %ld, %ld, %ld, %ld, ",
1237 *plRefCode, lDll, lFile, lLevel, lSeqNbrNote, lSeqNbr, lLine);
1238
1239 if (pszTitle != NULL && *pszTitle != '\0')
1240 sqlstrcat(&szQuery[0], NULL, pszTitle);
1241 else
1242 strcat(&szQuery[0], "NULL");
1243 sqlstrcat(&szQuery[0], ", ", pszText == NULL ? "" : pszText, ")");
1244
1245 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1246 {
1247 if (!fSubSection)
1248 *plRefCode = mysql_insert_id(pmysql);
1249 return TRUE;
1250 }
1251 return FALSE;
1252}
1253
1254
1255
1256/**
1257 * Updates the history tables.
1258 * @returns Number of signals/errors.
1259 * @param pszError Pointer to buffer which will hold the error messages.
1260 * @remark This should be called whenever updates have been completed.
1261 */
1262unsigned long _System dbCreateHistory(char *pszError)
1263{
1264 unsigned long ulRc = 0;
1265 MYSQL_RES *pres;
1266 MYSQL_ROW row;
1267 char szQuery[256];
1268 char *pszQuery = &szQuery[0];
1269 int rc;
1270 char szCurDt[20] = {0}; /*yyyy-mm-dd\0*/
1271
1272 mysql_refresh(pmysql, REFRESH_TABLES);
1273
1274 /* get currentdate - just in case the date changes between the delete and the update is completed. */
1275 strcpy(pszQuery, "SELECT CURDATE()");
1276 rc = mysql_query(pmysql, pszQuery);
1277 pres = mysql_use_result(pmysql);
1278 if (rc >= 0 && pres != NULL)
1279 {
1280 row = mysql_fetch_row(pres);
1281 if (row != NULL && mysql_num_rows(pres) == 1)
1282 {
1283 strcpy(&szCurDt[0], row[0]);
1284 while (mysql_fetch_row(pres) != NULL)
1285 pres=pres;
1286
1287 /* delete - all rows on this date in the history tables */
1288 sprintf(pszQuery, "DELETE FROM historydll WHERE date = '%s'", &szCurDt[0]);
1289 rc = mysql_query(pmysql, pszQuery);
1290 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1291
1292 sprintf(pszQuery, "DELETE FROM historyapigroup WHERE date = '%s'", &szCurDt[0]);
1293 rc = mysql_query(pmysql, pszQuery);
1294 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1295
1296 sprintf(pszQuery, "DELETE FROM historydlltotal WHERE date = '%s'", &szCurDt[0]);
1297 rc = mysql_query(pmysql, pszQuery);
1298 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1299
1300 sprintf(pszQuery, "DELETE FROM historyapigrouptotal WHERE date = '%s'", &szCurDt[0]);
1301 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1302
1303 /* insert new stats */
1304 sprintf(pszQuery, "INSERT INTO historydll(dll, state, date, count) "
1305 "SELECT dll, state, '%s', count(*) FROM function GROUP BY dll, state",
1306 &szCurDt[0]);
1307 rc = mysql_query(pmysql, pszQuery);
1308 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1309
1310 sprintf(pszQuery, "INSERT INTO historyapigroup(apigroup, state, date, count) "
1311 "SELECT apigroup, state, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
1312 "GROUP BY apigroup, state",
1313 &szCurDt[0]);
1314 rc = mysql_query(pmysql, pszQuery);
1315 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1316
1317 /* inserting new totals */
1318 sprintf(pszQuery, "INSERT INTO historydlltotal(dll, date, totalcount) "
1319 "SELECT dll, '%s', count(*) FROM function GROUP BY dll",
1320 &szCurDt[0]);
1321 rc = mysql_query(pmysql, pszQuery);
1322 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1323
1324 sprintf(pszQuery, "INSERT INTO historyapigrouptotal(apigroup, date, totalcount) "
1325 "SELECT apigroup, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
1326 "GROUP BY apigroup",
1327 &szCurDt[0]);
1328 rc = mysql_query(pmysql, pszQuery);
1329 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1330 }
1331 else
1332 {
1333 sprintf(pszError, "error getting current date (row == NULL): %s - (sql=%s) ",
1334 dbGetLastErrorDesc(), pszQuery);
1335 ulRc++;
1336 }
1337 }
1338 else
1339 {
1340 sprintf(pszError, "error getting current date: %s - (sql=%s) ",
1341 dbGetLastErrorDesc(), pszQuery);
1342 ulRc++;
1343 }
1344
1345 mysql_refresh(pmysql, REFRESH_TABLES);
1346
1347 return ulRc;
1348}
1349
1350
1351/**
1352 * Check that database integrety is ok. Verfies foreign keys.
1353 * @returns numbers of errors.
1354 * @param pszError Very large buffer which will hold error messges (if any).
1355 * @sketch
1356 * @remark current versions of mysql don't support 'SELECT ... WHERE id NOT IN(SELECT id FROM table)'
1357 */
1358unsigned long _System dbCheckIntegrity(char *pszError)
1359{
1360 char szQuery[384];
1361 char *pszQuery = &szQuery[0];
1362 MYSQL_RES *pres1;
1363 MYSQL_RES *pres2;
1364 MYSQL_ROW row1;
1365 int rc;
1366 unsigned long ulRc = 0;
1367
1368 mysql_refresh(pmysql, REFRESH_TABLES);
1369
1370 /* foreign keys in function table */
1371 strcpy(pszQuery, "SELECT refcode, dll, state, apigroup, file FROM function");
1372 rc = mysql_query(pmysql, pszQuery);
1373 if (rc >= 0)
1374 {
1375 pres1 = mysql_store_result(pmysql);
1376 if (pres1 != NULL)
1377 {
1378 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1379 {
1380 /* check dll */
1381 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1382 rc = mysql_query(pmysql, pszQuery);
1383 CheckFKError("function/dll", "Foreign key 'dll' not found in the dll table");
1384
1385 /* check state */
1386 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1387 rc = mysql_query(pmysql, pszQuery);
1388 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1389
1390 /* check apigroup */
1391 if (row1[3] != NULL)
1392 {
1393 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[3]);
1394 rc = mysql_query(pmysql, pszQuery);
1395 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1396 }
1397
1398 /* check file */
1399 if (atoi(row1[4]) >= 0)
1400 {
1401 sprintf(pszQuery, "SELECT refcode FROM file WHERE refcode = %s", row1[4]);
1402 rc = mysql_query(pmysql, pszQuery);
1403 CheckFKError("function/file", "Foreign key 'file' not found in the file table");
1404 }
1405 }
1406 mysql_free_result(pres1);
1407 }
1408 }
1409 else
1410 ulRc += logDbError(pszError, pszQuery);
1411
1412 /* foreign keys in file */
1413 strcpy(pszQuery, "SELECT refcode, dll FROM file");
1414 rc = mysql_query(pmysql, pszQuery);
1415 if (rc >= 0)
1416 {
1417 pres1 = mysql_store_result(pmysql);
1418 if (pres1 != NULL)
1419 {
1420 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1421 {
1422 /* check dll */
1423 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1424 rc = mysql_query(pmysql, pszQuery);
1425 CheckFKError("apigroup/dll", "Foreign key 'dll' not found in the dll table");
1426 }
1427 mysql_free_result(pres1);
1428 }
1429 }
1430 else
1431 ulRc += logDbError(pszError, pszQuery);
1432
1433 /* foreign keys in apigroup */
1434 strcpy(pszQuery, "SELECT refcode, dll FROM apigroup");
1435 rc = mysql_query(pmysql, pszQuery);
1436 if (rc >= 0)
1437 {
1438 pres1 = mysql_store_result(pmysql);
1439 if (pres1 != NULL)
1440 {
1441 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1442 {
1443 /* check dll */
1444 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1445 rc = mysql_query(pmysql, pszQuery);
1446 CheckFKError("file/dll", "Foreign key 'dll' not found in the dll table");
1447 }
1448 mysql_free_result(pres1);
1449 }
1450 }
1451 else
1452 ulRc += logDbError(pszError, pszQuery);
1453
1454 /* foreign keys in fnauthor */
1455 strcpy(pszQuery, "SELECT function, author FROM fnauthor");
1456 rc = mysql_query(pmysql, pszQuery);
1457 if (rc >= 0)
1458 {
1459 pres1 = mysql_store_result(pmysql);
1460 if (pres1 != NULL)
1461 {
1462 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1463 {
1464 /* check function */
1465 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1466 rc = mysql_query(pmysql, pszQuery);
1467 CheckFKError("fnauthor/function", "Foreign key 'function' not found in the function table");
1468
1469 /* check author */
1470 sprintf(pszQuery, "SELECT refcode FROM author WHERE refcode = %s", row1[1]);
1471 rc = mysql_query(pmysql, pszQuery);
1472 CheckFKError("fnauthor/author", "Foreign key 'author' not found in the author table");
1473 }
1474 mysql_free_result(pres1);
1475 }
1476 }
1477 else
1478 ulRc += logDbError(pszError, pszQuery);
1479
1480 /* foreign keys in historydll table */
1481 strcpy(pszQuery, "SELECT date, dll, state FROM historydll");
1482 rc = mysql_query(pmysql, pszQuery);
1483 if (rc >= 0)
1484 {
1485 pres1 = mysql_store_result(pmysql);
1486 if (pres1 != NULL)
1487 {
1488 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1489 {
1490 /* check dll */
1491 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1492 rc = mysql_query(pmysql, pszQuery);
1493 CheckFKError("historydll/dll", "Foreign key 'dll' not found in the dll table");
1494
1495 /* check state */
1496 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1497 rc = mysql_query(pmysql, pszQuery);
1498 CheckFKError("historydll/state", "Foreign key 'state' not found in the state table");
1499 }
1500 mysql_free_result(pres1);
1501 }
1502 }
1503 else
1504 ulRc += logDbError(pszError, pszQuery);
1505
1506 /* foreign keys in historyapigroup table */
1507 strcpy(pszQuery, "SELECT date, apigroup, state FROM historyapigroup");
1508 rc = mysql_query(pmysql, pszQuery);
1509 if (rc >= 0)
1510 {
1511 pres1 = mysql_store_result(pmysql);
1512 if (pres1 != NULL)
1513 {
1514 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1515 {
1516 /* check dll */
1517 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1518 rc = mysql_query(pmysql, pszQuery);
1519 CheckFKError("historyapigroup/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1520
1521 /* check state */
1522 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1523 rc = mysql_query(pmysql, pszQuery);
1524 CheckFKError("historyapigroup/state", "Foreign key 'state' not found in the state table");
1525 }
1526 mysql_free_result(pres1);
1527 }
1528 }
1529 else
1530 ulRc += logDbError(pszError, pszQuery);
1531
1532 /* foreign keys in historydlltotal table */
1533 strcpy(pszQuery, "SELECT date, dll FROM historydlltotal");
1534 rc = mysql_query(pmysql, pszQuery);
1535 if (rc >= 0)
1536 {
1537 pres1 = mysql_store_result(pmysql);
1538 if (pres1 != NULL)
1539 {
1540 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1541 {
1542 /* check dll */
1543 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1544 rc = mysql_query(pmysql, pszQuery);
1545 CheckFKError("historydlltotal/dll", "Foreign key 'dll' not found in the dll table");
1546 }
1547 mysql_free_result(pres1);
1548 }
1549 }
1550 else
1551 ulRc += logDbError(pszError, pszQuery);
1552
1553 /* foreign keys in historyapigroup table */
1554 strcpy(pszQuery, "SELECT date, apigroup FROM historyapigrouptotal");
1555 rc = mysql_query(pmysql, pszQuery);
1556 if (rc >= 0)
1557 {
1558 pres1 = mysql_store_result(pmysql);
1559 if (pres1 != NULL)
1560 {
1561 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1562 {
1563 /* check dll */
1564 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1565 rc = mysql_query(pmysql, pszQuery);
1566 CheckFKError("historyapigrouptotal/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1567 }
1568 mysql_free_result(pres1);
1569 }
1570 }
1571 else
1572 ulRc += logDbError(pszError, pszQuery);
1573
1574 /* foreign keys in parameter table */
1575 strcpy(pszQuery, "SELECT sequencenbr, function FROM parameter");
1576 rc = mysql_query(pmysql, pszQuery);
1577 if (rc >= 0)
1578 {
1579 pres1 = mysql_store_result(pmysql);
1580 if (pres1 != NULL)
1581 {
1582 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1583 {
1584 /* check function */
1585 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1586 rc = mysql_query(pmysql, pszQuery);
1587 CheckFKError("parameter/function", "Foreign key 'function' not found in the function table");
1588 }
1589 mysql_free_result(pres1);
1590 }
1591 }
1592 else
1593 ulRc += logDbError(pszError, pszQuery);
1594
1595 /* Author table is special, since you should be able to interchangably reference an
1596 * author by any of the following tables:
1597 * name
1598 * initials
1599 * alias
1600 * email
1601 */
1602 strcpy(pszQuery, "SELECT name, initials, alias, email FROM author");
1603 rc = mysql_query(pmysql, pszQuery);
1604 if (rc >= 0)
1605 {
1606 pres1 = mysql_store_result(pmysql);
1607 if (pres1 != NULL)
1608 {
1609 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1610 {
1611 /* check name */
1612 sprintf(pszQuery, "SELECT name FROM author WHERE "
1613 "initials = '%s' OR alias = '%s' OR email = '%s'",
1614 row1[0], row1[0], row1[0]);
1615 ulRc += CheckAuthorError(pszError, "name", row1[0], pszQuery);
1616
1617 /* check initials */
1618 sprintf(pszQuery, "SELECT name FROM author WHERE "
1619 "alias = '%s' OR email = '%s'",
1620 row1[1], row1[1]);
1621 ulRc += CheckAuthorError(pszError, "initials", row1[1], pszQuery);
1622
1623 /* alias */
1624 if (row1[2] != NULL)
1625 {
1626 sprintf(pszQuery, "SELECT name FROM author WHERE "
1627 "email = '%s'",
1628 row1[2]);
1629 ulRc += CheckAuthorError(pszError, "alias", row1[2], pszQuery);
1630 }
1631 }
1632 mysql_free_result(pres1);
1633 }
1634 }
1635 else
1636 ulRc += logDbError(pszError, pszQuery);
1637
1638 return ulRc;
1639}
1640
1641
1642/**
1643 * Checks for duplicate key and sql error for a given author key in the author table... (arg!)
1644 * @returns Number of errors.
1645 * @param pszError Reference to error buffer pointer.
1646 * @param pszFieldName Key field name; used for logging.
1647 * @param pszFieldValue Key value; used for logging
1648 * @param pszQuery Query which is to be exectued to test for duplicate key.
1649 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1650 */
1651static unsigned long CheckAuthorError(char * &pszError, const char *pszFieldName, const char *pszFieldValue, const char *pszQuery)
1652{
1653 MYSQL_ROW row;
1654 MYSQL_RES *pres;
1655 unsigned long ulRc = 0;
1656 int rc;
1657
1658 rc = mysql_query(pmysql, pszQuery);
1659 pres = mysql_store_result(pmysql);
1660 if (rc < 0 || (pres != NULL && mysql_num_rows(pres) != 0))
1661 { /* some kind of error has occurred */
1662 if (pszError[1] == '\xFE')
1663 {
1664 strcat(pszError, "\n\t");
1665 pszError += 2;
1666 }
1667
1668 if (rc < 0) /* sql error or 'duplicate key' */
1669 {
1670 sprintf(pszError, "author/%s: select failed - %s (sql=%s)",
1671 pszFieldName, dbGetLastErrorDesc(), pszQuery);
1672 }
1673 else
1674 { /* 'duplicate key' - print duplicates */
1675 sprintf(pszError, "author/%s: 'duplicate key', %s='%s': ",
1676 pszFieldName, pszFieldValue, pszFieldName);
1677
1678 while ((row = mysql_fetch_row(pres)) != NULL)
1679 {
1680 pszError += strlen(pszError);
1681 sprintf(pszError, "'%s' ", row[0]);
1682 }
1683 }
1684
1685 pszError += strlen(pszError);
1686 pszError[1] = '\xFE';
1687 ulRc = 1;
1688 }
1689 if (pres != NULL)
1690 mysql_free_result(pres);
1691
1692 return ulRc;
1693}
1694
1695
1696/**
1697 * Writes db error (rc<0) to the log buffer.
1698 * @returns Number of signals.
1699 * @param pszError Reference to the error buffer pointer.
1700 * @param pszQuery Pointer to query which was executed.
1701 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1702 */
1703static unsigned long logDbError(char * &pszError, const char *pszQuery)
1704{
1705 if (pszError[1] == '\xFE')
1706 {
1707 strcat(pszError, "\n\t");
1708 pszError += 2;
1709 }
1710 sprintf(pszError, "select failed: %s - (sql=%s)", dbGetLastErrorDesc(), pszQuery);
1711
1712 pszError += strlen(pszError);
1713 pszError[1] = '\xFE';
1714
1715 return 1;
1716}
1717
1718
1719/**
1720 * Executes a give query and returns a result identifier/pointer.
1721 * @returns Query result identifier/pointer. NULL on error.
1722 * @param pszQuery Pointer to query.
1723 * @remark Used by and designed for kHtmlPC.
1724 */
1725void * _System dbExecuteQuery(const char *pszQuery)
1726{
1727 assert(pmysql != NULL);
1728 if (mysql_query(pmysql, pszQuery) >= 0)
1729 return mysql_store_result(pmysql);
1730
1731 return NULL;
1732}
1733
1734
1735/**
1736 * Asks for the number of rows in the result.
1737 * @returns Number of rows in the result. -1 on error.
1738 * @param pres Query result identifier/pointer.
1739 * @remark Used by and designed for kHtmlPC.
1740 */
1741signed long _System dbQueryResultRows(void *pres)
1742{
1743 if (pres == NULL)
1744 return -1;
1745 return mysql_num_rows((MYSQL_RES*)pres);
1746}
1747
1748
1749/**
1750 * Frees the storage allocated by the given result.
1751 * @returns Success indicator, TRUE/FALSE.
1752 * @param pres Query result identifier/pointer.
1753 * @remark Used by and designed for kHtmlPC.
1754 */
1755BOOL _System dbFreeResult(void *pres)
1756{
1757 if (pres != NULL)
1758 mysql_free_result((MYSQL_RES*)pres);
1759 else
1760 return FALSE;
1761 return TRUE;
1762}
1763
1764
1765/**
1766 * Fetch data from a result. Returns the data by calling the given callback function.
1767 * @returns Success indicator, TRUE/FALSE.
1768 * @param pres Query result identifier/pointer.
1769 * @param dbFetchCallBack Callback-function.
1770 * @param pvUser User parameter which is passed onto dbFetchCallBack.
1771 * @remark Used by and designed for kHtmlPC.
1772 */
1773BOOL _System dbFetch(void *pres, DBCALLBACKFETCH dbFetchCallBack, void *pvUser)
1774{
1775 BOOL fRc = FALSE;
1776 MYSQL_ROW row = mysql_fetch_row((MYSQL_RES*)pres);
1777
1778 if (row)
1779 {
1780 MYSQL_FIELD *pField;
1781 int i = 0;
1782 mysql_field_seek((MYSQL_RES*)pres, 0);
1783
1784 while ((pField = mysql_fetch_field((MYSQL_RES*)pres)) != NULL)
1785 if (dbFetchCallBack(row[i++], pField->name, pvUser) != 0)
1786 return FALSE;
1787
1788 fRc = TRUE;
1789 }
1790
1791 return fRc;
1792}
1793
1794
1795/**
1796 * Converts an ISO date to days after Christ, year 0.
1797 * @returns days. -1 on error;
1798 * @param pszDate ISO Date.
1799 */
1800signed long _System dbDateToDaysAfterChrist(const char *pszDate)
1801{
1802 signed long lRet = -1;
1803 char szQuery[128];
1804
1805 sprintf(&szQuery[0], "SELECT to_days('%s')", pszDate);
1806 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1807 {
1808 MYSQL_ROW row;
1809 MYSQL_RES *pres = mysql_use_result(pmysql);
1810 row = mysql_fetch_row(pres);
1811 if (row != NULL)
1812 {
1813 lRet = atol(row[0]);
1814 do { row = mysql_fetch_row(pres); } while (row != NULL);
1815 }
1816 }
1817
1818 return lRet;
1819}
1820
1821
1822/**
1823 * Converts days after Christ (year 0) to ISO date.
1824 * @returns Success indicator. TRUE/FALSE;
1825 * @param lDays Days after Christ (year 0).
1826 * @param pszDate ISO Date. Result.
1827 */
1828BOOL _System dbDaysAfterChristToDate(signed long lDays, char *pszDate)
1829{
1830 BOOL fRet = FALSE;
1831 char szQuery[128];
1832
1833 if (lDays < 0)
1834 return FALSE;
1835
1836 sprintf(&szQuery[0], "SELECT from_days(%ld)", lDays);
1837 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1838 {
1839 MYSQL_ROW row;
1840 MYSQL_RES *pres = mysql_use_result(pmysql);
1841 row = mysql_fetch_row(pres);
1842 if (row != NULL)
1843 {
1844 fRet = strlen(row[0]) == (4+1+2+1+2) && row[0][4] == '-' && row[0][7] == '-'
1845 && strcmp(row[0], "0000-00-00") != 0;
1846 if (fRet)
1847 strcpy(pszDate, row[0]);
1848 do { row = mysql_fetch_row(pres); } while (row != NULL);
1849 }
1850 }
1851
1852 return fRet;
1853}
1854
1855
1856/**
1857 * Display all functions for, the given dll, that is not updated.
1858 * @returns TRUE / FALSE.
1859 * @param lDll Dll reference number.
1860 * @param dbFetchCall Callback function which will be called once for each
1861 * field for all the functions not updated.
1862 * pvUser is NULL, pszValue field value, pszFieldName the field name.
1863 */
1864BOOL _System dbGetNotUpdatedFunction(signed long lDll, DBCALLBACKFETCH dbFetchCallBack)
1865{
1866 BOOL fRet = FALSE;
1867 void *pres;
1868 char szQuery[256];
1869
1870 /* not updated names */
1871 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1872 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1873 " LEFT JOIN dll d ON f2.dll = d.refcode "
1874 "WHERE f1.dll = %ld AND f1.updated = 0",
1875 lDll);
1876 pres = dbExecuteQuery(szQuery);
1877 if (pres != NULL)
1878 {
1879 BOOL f;
1880 do
1881 {
1882 f = dbFetch(pres, dbFetchCallBack, NULL);
1883 } while (f);
1884 dbFreeResult(pres);
1885 fRet = TRUE;
1886 }
1887
1888 /* warn about updated > 1 too */
1889 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1890 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1891 " LEFT JOIN dll d ON f2.dll = d.refcode "
1892 "WHERE f1.dll = %ld AND f1.updated > 1",
1893 lDll);
1894 pres = dbExecuteQuery(szQuery);
1895 if (pres != NULL)
1896 {
1897 BOOL f;
1898 do
1899 {
1900 f = dbFetch(pres, dbFetchCallBack, NULL);
1901 } while (f);
1902 dbFreeResult(pres);
1903 fRet = TRUE;
1904 }
1905
1906 strcpy(&szQuery[0], "UPDATE function SET updated = 0");
1907 mysql_query(pmysql, &szQuery[0]);
1908
1909 return fRet;
1910}
1911
1912
1913/**
1914 * Counts the function for the given DLL which has been updated.
1915 * @returns -1 on error, number of updated function on success.
1916 * @param lDll Dll reference number.
1917 */
1918signed long _System dbGetNumberOfUpdatedFunction(signed long lDll)
1919{
1920 int rc;
1921 char szQuery[128];
1922 MYSQL_RES * pres;
1923
1924 sprintf(&szQuery[0], "SELECT count(*) FROM function WHERE dll = (%ld) AND updated > 0\n", lDll);
1925 rc = mysql_query(pmysql, &szQuery[0]);
1926 pres = mysql_store_result(pmysql);
1927 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
1928 rc = (int)getvalue(0, mysql_fetch_row(pres));
1929 else
1930 rc = -1;
1931 mysql_free_result(pres);
1932 return (signed long)rc;
1933}
1934
1935
1936
1937/**
1938 * Clear the update flags for all file in a dll/module.
1939 * @returns Success indicator. (TRUE / FALSE)
1940 * @param lDll Dll refcode.
1941 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1942 * @remark Intended for use by APIImport.
1943 */
1944BOOL _System dbClearUpdateFlagFile(signed long lDll)
1945{
1946 int rc;
1947 char szQuery[128];
1948
1949 sprintf(&szQuery[0],
1950 "UPDATE file SET updated = 0 WHERE dll = (%ld)",
1951 lDll);
1952 rc = mysql_query(pmysql, &szQuery[0]);
1953 return rc == 0;
1954}
1955
1956
1957/**
1958 * Clear update flag
1959 * @returns Success indicator.
1960 * @param lDll Dll refcode.
1961 * @param fAll All dll. If false only APIs and Internal APIs are cleared
1962 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1963 * @remark Intended for use by APIImport.
1964 */
1965BOOL _System dbClearUpdateFlagFunction(signed long lDll, BOOL fAll)
1966{
1967 int rc;
1968 char szQuery[128];
1969
1970 sprintf(&szQuery[0],
1971 "UPDATE function SET updated = 0 WHERE dll = (%ld)",
1972 lDll);
1973 if (!fAll)
1974 strcat(&szQuery[0], " AND type IN ('A', 'I')");
1975 rc = mysql_query(pmysql, &szQuery[0]);
1976 return rc == 0;
1977}
1978
1979
1980
1981/**
1982 * Deletes all the files in a dll/module which was not found/updated.
1983 * @returns Success indicator.
1984 * @param lDll Dll refcode.
1985 * @sketch Select all files which is to be deleted.
1986 * Set all references to each file in function to -1.
1987 * Delete all files which is to be deleted.
1988 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1989 * @remark Use with GRATE CARE!
1990 */
1991BOOL _System dbDeleteNotUpdatedFiles(signed long lDll)
1992{
1993 MYSQL_RES * pres;
1994 int rc;
1995 BOOL fRc = TRUE;
1996 char szQuery[128];
1997
1998 sprintf(&szQuery[0],
1999 "SELECT refcode FROM file WHERE dll = (%ld) AND updated = 0",
2000 lDll);
2001 rc = mysql_query(pmysql, &szQuery[0]);
2002 pres = mysql_store_result(pmysql);
2003 if (pres != NULL && mysql_num_rows(pres))
2004 {
2005 MYSQL_ROW row;
2006 while ((row = mysql_fetch_row(pres)) != NULL)
2007 {
2008 sprintf(&szQuery[0],
2009 "UPDATE function SET file = -1 WHERE file = %s",
2010 row[0]);
2011 rc = mysql_query(pmysql, &szQuery[0]);
2012 if (rc) fRc = FALSE;
2013 }
2014 }
2015
2016 sprintf(&szQuery[0],
2017 "DELETE FROM file WHERE dll = %ld AND updated = 0",
2018 lDll);
2019 rc = mysql_query(pmysql, &szQuery[0]);
2020 if (rc) fRc = FALSE;
2021
2022 return fRc;
2023}
2024
2025
2026/**
2027 * Deletes all the functions which haven't been updated.
2028 * All rows in other tables which references the functions are
2029 * also delete.
2030 *
2031 * @returns Success indicator. (TRUE / FALSE)
2032 * @param lDll The refcode of the dll owning the functions.
2033 * @param fAll All function. If FALSE then only APIs and Internal APIs.
2034 * @sketch Select all functions which wan't updated (ie. updated = 0 and dll = lDll).
2035 * If anyone Then
2036 * Delete the referenced to the functions in:
2037 * parameters
2038 * fnauthor
2039 * Delete all function which wasn't updated.
2040 * EndIf
2041 * @remark Use with GREATE CARE!
2042 */
2043BOOL _System dbDeleteNotUpdatedFunctions(signed long lDll, BOOL fAll)
2044{
2045 MYSQL_RES * pres;
2046 int rc;
2047 BOOL fRc = TRUE;
2048 char szQuery[128];
2049
2050 sprintf(&szQuery[0],
2051 "SELECT refcode FROM function WHERE dll = %ld AND updated = 0",
2052 lDll);
2053 if (!fAll)
2054 strcat(&szQuery[0], " AND type IN ('A', 'I')");
2055 rc = mysql_query(pmysql, &szQuery[0]);
2056 pres = mysql_store_result(pmysql);
2057
2058 if (pres != NULL && mysql_num_rows(pres))
2059 {
2060 MYSQL_ROW row;
2061 while ((row = mysql_fetch_row(pres)) != NULL)
2062 {
2063 /* delete parameters */
2064 sprintf(&szQuery[0], "DELETE FROM parameter WHERE function = %s", row[0]);
2065 rc = mysql_query(pmysql, &szQuery[0]);
2066 if (rc) fRc = FALSE;
2067
2068 /* author relations */
2069 sprintf(&szQuery[0], "DELETE FROM fnauthor WHERE function = %s", row[0]);
2070 rc = mysql_query(pmysql, &szQuery[0]);
2071 if (rc) fRc = FALSE;
2072 }
2073
2074 /*
2075 * Delete the functions only if above completed without errors.
2076 *
2077 * Deleting the functions before all the references has successfully be
2078 * deleted causes database corruption!
2079 */
2080 if (fRc)
2081 {
2082 sprintf(&szQuery[0],
2083 "DELETE FROM function WHERE dll = %ld AND updated = 0",
2084 lDll);
2085 if (!fAll)
2086 strcat(&szQuery[0], " AND type IN ('A', 'I')");
2087 rc = mysql_query(pmysql, &szQuery[0]);
2088 if (rc) fRc = FALSE;
2089 }
2090 }
2091
2092 return fRc;
2093}
2094
2095
2096
2097/**
2098 * Appends a set of strings to a query. The main string (pszStr) is enclosed in "'"s.
2099 * @returns Pointer to end of the string.
2100 * @param pszQuery Outputbuffer
2101 * @param pszBefore Text before string, might be NULL.
2102 * @param pszStr String (NOT NULL)
2103 * @param pszAfter Text after, might be NULL.
2104 * @status completely implemented
2105 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
2106 */
2107static char *sqlstrcat(char *pszQuery, const char *pszBefore, const char *pszStr, const char *pszAfter)
2108{
2109 char * pszLineStart = pszQuery;
2110 register char ch;
2111
2112 pszQuery += strlen(pszQuery);
2113
2114 /*
2115 * String before
2116 */
2117 if (pszBefore != NULL)
2118 {
2119 strcpy(pszQuery, pszBefore);
2120 pszQuery += strlen(pszQuery);
2121 }
2122
2123 /*
2124 * THE String
2125 */
2126 *pszQuery++ = '\'';
2127 while ((ch = *pszStr++) != '\0')
2128 {
2129 switch (ch)
2130 {
2131 case '\'':
2132 *pszQuery++ = '\\';
2133 *pszQuery++ = '\'';
2134 break;
2135
2136 case '"':
2137 *pszQuery++ = '\\';
2138 *pszQuery++ = '"';
2139 break;
2140
2141 case '\\':
2142 *pszQuery++ = '\\';
2143 *pszQuery++ = '\\';
2144 break;
2145
2146 case '%':
2147 *pszQuery++ = '\\';
2148 *pszQuery++ = '%';
2149 break;
2150
2151 case '_':
2152 *pszQuery++ = '\\';
2153 *pszQuery++ = '_';
2154 break;
2155
2156 case '\n':
2157 *pszQuery++ = '\\';
2158 *pszQuery++ = 'r';
2159 *pszQuery++ = '\\';
2160 *pszQuery++ = 'n';
2161 break;
2162
2163 case '\t':
2164 *pszQuery++ = '\\';
2165 *pszQuery++ = 't';
2166 break;
2167
2168 case '\r':
2169 break;
2170
2171 default:
2172 *pszQuery++ = ch;
2173 }
2174
2175 /* Add new lines every 80 chars MySql don't like long lines. */
2176 if (pszLineStart - pszQuery > 80)
2177 {
2178 *pszQuery = '\n';
2179 pszLineStart = pszQuery;
2180 }
2181 }
2182 *pszQuery++ = '\'';
2183
2184 /*
2185 * String after
2186 */
2187 if (pszAfter != NULL)
2188 {
2189 strcpy(pszQuery, pszAfter);
2190 pszQuery += strlen(pszQuery);
2191 }
2192 else
2193 *pszQuery = '\0';
2194
2195
2196 return pszQuery;
2197}
2198
2199
2200#ifndef DLL
2201/**
2202 * Signal handler.
2203 * Ensures that the database connection is closed at termination.
2204 * @param sig Signal number.
2205 */
2206void dbHandler(int sig)
2207{
2208 if (pmysql != NULL)
2209 {
2210 fprintf(stderr, "\n\t!disconnecting from database!\n");
2211 dbDisconnect();
2212 }
2213
2214 flushall();
2215 switch (sig)
2216 {
2217 case SIGBREAK:
2218 printf("\nSIGBREAK\n");
2219 exit(-1);
2220 break;
2221 case SIGINT:
2222 printf("\nSIGINT\n");
2223 exit(-1);
2224 break;
2225 case SIGTERM:
2226 printf("\nSIGTERM\n");
2227 exit(-1);
2228 break;
2229 case SIGSEGV:
2230 raise(sig);
2231 break;
2232 case SIGILL:
2233 printf("\nSIGILL\n");
2234 exit(-1);
2235 break;
2236 }
2237}
2238
2239
2240#else
2241/*******/
2242/* DLL */
2243/*******/
2244/* prototypes used in the _DLL_InitTerm function */
2245extern "C"
2246{
2247 int _CRT_init(void);
2248 void _CRT_term(void);
2249 void __ctordtorInit( void );
2250 void __ctordtorTerm( void );
2251 unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag);
2252}
2253
2254
2255/**
2256 * Dll InitTerm function.
2257 * @returns 0 on success.
2258 * 1 on error.
2259 * @param hModule
2260 * @param ulFlags
2261 * @remark We'll ensure that the database connection is terminated as we terminate.
2262 */
2263unsigned long _System _DLL_InitTerm(unsigned long hModule, unsigned long ulFlag)
2264{
2265 /*-------------------------------------------------------------------------*/
2266 /* If ulFlag is zero then the DLL is being loaded so initialization should */
2267 /* be performed. If ulFlag is 1 then the DLL is being freed so */
2268 /* termination should be performed. */
2269 /*-------------------------------------------------------------------------*/
2270
2271 switch (ulFlag)
2272 {
2273 case 0:
2274 if (_CRT_init() == -1)
2275 return 0;
2276 __ctordtorInit();
2277 break;
2278
2279 case 1:
2280 /* ensure that db connection is terminated */
2281 if (pmysql != NULL)
2282 {
2283 fprintf(stderr, "\n\t!disconnecting from database!\n");
2284 dbDisconnect();
2285 }
2286 __ctordtorTerm();
2287 break;
2288
2289 default:
2290 return 0;
2291 }
2292 hModule = hModule;
2293 return 1;
2294}
2295
2296/*****************************************************************/
2297/* -why is this terminate function referenced but not defined??? */
2298/* and where is it referenced??? */
2299/* -Probably an export missing from the libraries. */
2300/*****************************************************************/
2301void terminate(void)
2302{
2303 DosPutMessage(0, sizeof("terminate")-1, "terminate");
2304 exit(-1);
2305}
2306
2307/****************************************/
2308/* EMX run-time trouble */
2309/* _environ is missing when using -Zomf */
2310/****************************************/
2311char **_environ = environ;
2312
2313#endif
Note: See TracBrowser for help on using the repository browser.