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

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

Corrections and handling of the updated field in function and file.

File size: 76.2 KB
Line 
1/* $Id: db.cpp,v 1.16 2000-07-21 21:09:44 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 BOOL f = FALSE;
908
909 /*
910 * Set updated flag
911 */
912 sprintf(pszQuery, "UPDATE function SET updated = updated + 1 WHERE refcode = %ld",
913 pFnDesc->alRefCode[k]);
914 rc = mysql_queryu1(pmysql, pszQuery2);
915
916
917 /*
918 * Get current status
919 */
920 lCurrentState = dbGetFunctionState(pFnDesc->alRefCode[k]);
921 if (lCurrentState == -1 && dbGetLastErrorDesc() != NULL && strlen(dbGetLastErrorDesc()) != 0)
922 {
923 strcpy(pszError, dbGetLastErrorDesc());
924 free(pszQuery2);
925 return 1;
926 }
927
928
929 /*
930 * Update function table first
931 */
932 strcpy(pszQuery, "UPDATE function SET ");
933 pszQuery += strlen(pszQuery);
934
935 /* Status */
936 if (lCurrentState != pFnDesc->lStatus
937 && pFnDesc->lStatus != 0
938 && (lCurrentState == 0 || pFnDesc->lStatus != 99))
939 {
940 sprintf(pszQuery, "state = %ld", pFnDesc->lStatus);
941 f = TRUE;
942 }
943 pszQuery += strlen(pszQuery);
944
945 /* return type */
946 if (pFnDesc->pszReturnType != NULL)
947 {
948 if (f) strcat(pszQuery, ", ");
949 pszQuery = sqlstrcat(pszQuery, "return = ", pFnDesc->pszReturnType);
950 f = TRUE;
951 }
952
953 /* Description */
954 if (pFnDesc->pszDescription != NULL)
955 {
956 if (f) strcat(pszQuery, ", ");
957 pszQuery = sqlstrcat(pszQuery, "description = ", pFnDesc->pszDescription);
958 f = TRUE;
959 }
960
961 /* Remark */
962 if (pFnDesc->pszRemark != NULL)
963 {
964 if (f) strcat(pszQuery, ", ");
965 pszQuery = sqlstrcat(pszQuery, "remark = ", pFnDesc->pszRemark);
966 f = TRUE;
967 }
968
969 /* Description */
970 if (pFnDesc->pszReturnDesc != NULL)
971 {
972 if (f) strcat(pszQuery, ", ");
973 pszQuery = sqlstrcat(pszQuery, "returndesc = ", pFnDesc->pszReturnDesc);
974 f = TRUE;
975 }
976
977 /* Sketch */
978 if (pFnDesc->pszSketch != NULL)
979 {
980 if (f) strcat(pszQuery, ", ");
981 pszQuery = sqlstrcat(pszQuery, "sketch = ", pFnDesc->pszSketch);
982 f = TRUE;
983 }
984
985 /* Equiv */
986 if (pFnDesc->pszEquiv != NULL)
987 {
988 if (f) strcat(pszQuery, ", ");
989 pszQuery = sqlstrcat(pszQuery, "equiv = ", pFnDesc->pszEquiv);
990 f = TRUE;
991 }
992
993 /* Time */
994 if (pFnDesc->pszTime != NULL)
995 {
996 if (f) strcat(pszQuery, ", ");
997 pszQuery = sqlstrcat(pszQuery, "time = ", pFnDesc->pszTime);
998 f = TRUE;
999 }
1000
1001 /* Execute update query? */
1002 if (f)
1003 {
1004 sprintf(pszQuery + strlen(pszQuery), " WHERE refcode = %ld", pFnDesc->alRefCode[k]);
1005 rc = mysql_queryu2(pmysql, pszQuery2);
1006 if (rc < 0)
1007 {
1008 sprintf(pszError, "Updating functiontable failed with error: %s - (sql=%s) ",
1009 dbGetLastErrorDesc(), pszQuery2);
1010 pszError += strlen(pszError) - 1;
1011 ulRc++;
1012 }
1013 }
1014
1015
1016
1017 /*
1018 * Parameters
1019 */
1020 pszQuery = pszQuery2;
1021 sprintf(pszQuery, "SELECT count(*) FROM parameter WHERE function = %ld", pFnDesc->alRefCode[k]);
1022 rc = mysql_queryu3(pmysql, pszQuery);
1023 if (rc >= 0)
1024 {
1025 pres = mysql_store_result(pmysql);
1026 if (pres != NULL)
1027 row = mysql_fetch_row(pres);
1028 if (pres != NULL && row != NULL && mysql_num_rows(pres) == 1)
1029 {
1030 if (atol(row[0]) == pFnDesc->cParams)
1031 { /* update parameters */
1032 for (i = 0; i < pFnDesc->cParams; i++)
1033 {
1034 sprintf(pszQuery, "UPDATE parameter SET type = '%s', name = '%s'",
1035 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
1036 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : "");
1037 if (pFnDesc->apszParamDesc[i] != NULL)
1038 sqlstrcat(pszQuery, ", description = ", pFnDesc->apszParamDesc[i]);
1039 sprintf(pszQuery + strlen(pszQuery), " WHERE function = (%ld) AND sequencenbr = (%ld)",
1040 pFnDesc->alRefCode[k], i);
1041 rc = mysql_queryu4(pmysql, pszQuery);
1042 if (rc < 0)
1043 {
1044 if (*pszError == ' ')
1045 strcpy(pszError++, "\n\t");
1046 sprintf(pszError, "Updateing parameter %i failed with error: %s - (sql=%s) ",
1047 i, dbGetLastErrorDesc(), pszQuery);
1048 pszError += strlen(pszError) - 1;
1049 ulRc++;
1050 }
1051 }
1052 }
1053 else
1054 {
1055 if (atol(row[0]) != 0)
1056 { /* delete old parameters */
1057 sprintf(pszQuery, "DELETE FROM parameter WHERE function = %ld", pFnDesc->alRefCode[k]);
1058 rc = mysql_queryu5(pmysql, pszQuery);
1059 if (rc < 0)
1060 {
1061 if (*pszError == ' ')
1062 strcpy(pszError++, "\n\t");
1063 sprintf(pszError, "Deleting old parameters failed with error: %s - (sql=%s) ",
1064 dbGetLastErrorDesc(), pszQuery);
1065 pszError += strlen(pszError) - 1;
1066 ulRc++;
1067 }
1068 }
1069
1070 /* insert parameters */
1071 for (i = 0; i < pFnDesc->cParams; i++)
1072 {
1073 sprintf(pszQuery, "INSERT INTO parameter(function, sequencenbr, type, name, description) "
1074 "VALUES (%ld, %d, '%s', '%s'",
1075 pFnDesc->alRefCode[k], i,
1076 pFnDesc->apszParamType[i] != NULL ? pFnDesc->apszParamType[i] : "",
1077 pFnDesc->apszParamName[i] != NULL ? pFnDesc->apszParamName[i] : ""
1078 );
1079 if (pFnDesc->apszParamDesc[i] != NULL)
1080 sqlstrcat(pszQuery, ", ", pFnDesc->apszParamDesc[i]);
1081 else
1082 strcat(pszQuery, ", NULL)");
1083
1084 rc = mysql_queryu6(pmysql, pszQuery2);
1085 if (rc < 0)
1086 {
1087 if (*pszError == ' ')
1088 strcpy(pszError++, "\n\t");
1089 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
1090 i, dbGetLastErrorDesc(), pszQuery);
1091 pszError += strlen(pszError) - 1;
1092 ulRc++;
1093 }
1094 }
1095 }
1096 }
1097 else
1098 {
1099 if (*pszError == ' ')
1100 strcpy(pszError++, "\n\t");
1101 sprintf(pszError, "failed to store result or to fetch a row , error: %s - (sql=%s) ",
1102 dbGetLastErrorDesc(), pszQuery);
1103 pszError += strlen(pszError) - 1;
1104 ulRc++;
1105 }
1106 }
1107 else
1108 {
1109 if (*pszError == ' ')
1110 strcpy(pszError++, "\n\t");
1111 sprintf(pszError, "Failed querying number of parameters, error: %s - (sql=%s) ",
1112 dbGetLastErrorDesc(), pszQuery);
1113 pszError += strlen(pszError) - 1;
1114 ulRc++;
1115 }
1116
1117
1118 /*
1119 * Authors
1120 */
1121 sprintf(pszQuery, "DELETE FROM fnauthor WHERE function = %ld", pFnDesc->alRefCode[k]);
1122 rc = mysql_queryu7(pmysql, pszQuery);
1123 if (rc < 0)
1124 {
1125 if (*pszError == ' ')
1126 strcpy(pszError++, "\n\t");
1127 sprintf(pszError, "Deleting old authors failed with error: %s - (sql=%s) ",
1128 dbGetLastErrorDesc(), pszQuery);
1129 pszError += strlen(pszError) - 1;
1130 ulRc++;
1131 }
1132
1133 for (i = 0; i < pFnDesc->cAuthors; i++)
1134 {
1135 if (pFnDesc->alAuthorRefCode[i] == -1)
1136 continue;
1137 sprintf(pszQuery, "INSERT INTO fnauthor(author, function) "
1138 "VALUES (%ld, %ld)",
1139 pFnDesc->alAuthorRefCode[i], pFnDesc->alRefCode[k]);
1140 rc = mysql_queryu8(pmysql, pszQuery);
1141 if (rc < 0)
1142 {
1143 if (*pszError == ' ')
1144 strcpy(pszError++, "\n\t");
1145 sprintf(pszError, "Inserting parameter %i failed with error: %s - (sql=%s) ",
1146 i, dbGetLastErrorDesc(), pszQuery);
1147 pszError += strlen(pszError) - 1;
1148 ulRc++;
1149 }
1150 }
1151 } /* for */
1152
1153 lDll = lDll;
1154 free(pszQuery2);
1155 return ulRc;
1156}
1157
1158
1159/**
1160 * Removes all the existing design notes in the specified file.
1161 * @returns Success indicator.
1162 * @param lFile File refcode of the file to remove all design notes for.
1163 * @sketch
1164 * @status
1165 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
1166 * @remark
1167 */
1168BOOL _System dbRemoveDesignNotes(signed long lFile)
1169{
1170 char szQuery[80];
1171
1172 assert(lFile >= 0);
1173 sprintf(&szQuery[0], "DELETE FROM designnote WHERE file = %ld", lFile);
1174 return mysql_query(pmysql, &szQuery[0]) >= 0;
1175}
1176
1177
1178/**
1179 * Adds a design note.
1180 * @returns Success indicator.
1181 * @param lDll Dll refcode.
1182 * @param lFile File refcode.
1183 * @param pszTitle Design note title.
1184 * @param pszText Design note text.
1185 * @param lSeqNbr Sequence number (in dll). If 0 the use next available number.
1186 * @param lSeqNbrFile Sequence number in file.
1187 */
1188BOOL _System dbAddDesignNote(signed long lDll,
1189 signed long lFile,
1190 const char *pszTitle,
1191 const char *pszText,
1192 signed long lSeqNbr,
1193 signed long lSeqNbrFile)
1194{
1195 char szQuery[0x10200];
1196 MYSQL_RES * pres;
1197
1198
1199 assert(lDll >= 0 && lFile >= 0);
1200 assert(lSeqNbrFile >= 0);
1201
1202 /*
1203 * If no lSqlNbr the make one.
1204 */
1205 if (lSeqNbr == 0)
1206 {
1207 sprintf(&szQuery[0], "SELECT MAX(lSeqNbr) + 1 FROM designnote WHERE dll = %ld'", 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)
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 update query.
1229 */
1230 sprintf(&szQuery[0], "INSERT INTO designnote(dll, file, seqnbrfile, seqnbr, title, note) "
1231 "VALUES (%ld, %ld, %ld, %ld, ",
1232 lDll, lFile, lSeqNbrFile, lSeqNbr);
1233 if (pszTitle != NULL && *pszTitle != '\0')
1234 sqlstrcat(&szQuery[0], NULL, pszTitle);
1235 else
1236 strcat(&szQuery[0], "NULL");
1237 sqlstrcat(&szQuery[0], ", ", pszText == NULL ? "" : pszText, ")");
1238
1239 return mysql_query(pmysql, &szQuery[0]) >= 0;
1240}
1241
1242
1243
1244/**
1245 * Updates the history tables.
1246 * @returns Number of signals/errors.
1247 * @param pszError Pointer to buffer which will hold the error messages.
1248 * @remark This should be called whenever updates have been completed.
1249 */
1250unsigned long _System dbCreateHistory(char *pszError)
1251{
1252 unsigned long ulRc = 0;
1253 MYSQL_RES *pres;
1254 MYSQL_ROW row;
1255 char szQuery[256];
1256 char *pszQuery = &szQuery[0];
1257 int rc;
1258 char szCurDt[20] = {0}; /*yyyy-mm-dd\0*/
1259
1260 mysql_refresh(pmysql, REFRESH_TABLES);
1261
1262 /* get currentdate - just in case the date changes between the delete and the update is completed. */
1263 strcpy(pszQuery, "SELECT CURDATE()");
1264 rc = mysql_query(pmysql, pszQuery);
1265 pres = mysql_use_result(pmysql);
1266 if (rc >= 0 && pres != NULL)
1267 {
1268 row = mysql_fetch_row(pres);
1269 if (row != NULL && mysql_num_rows(pres) == 1)
1270 {
1271 strcpy(&szCurDt[0], row[0]);
1272 while (mysql_fetch_row(pres) != NULL)
1273 pres=pres;
1274
1275 /* delete - all rows on this date in the history tables */
1276 sprintf(pszQuery, "DELETE FROM historydll WHERE date = '%s'", &szCurDt[0]);
1277 rc = mysql_query(pmysql, pszQuery);
1278 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1279
1280 sprintf(pszQuery, "DELETE FROM historyapigroup WHERE date = '%s'", &szCurDt[0]);
1281 rc = mysql_query(pmysql, pszQuery);
1282 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1283
1284 sprintf(pszQuery, "DELETE FROM historydlltotal WHERE date = '%s'", &szCurDt[0]);
1285 rc = mysql_query(pmysql, pszQuery);
1286 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1287
1288 sprintf(pszQuery, "DELETE FROM historyapigrouptotal WHERE date = '%s'", &szCurDt[0]);
1289 CheckLogContinue((pszError, "error removing old history rows: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1290
1291 /* insert new stats */
1292 sprintf(pszQuery, "INSERT INTO historydll(dll, state, date, count) "
1293 "SELECT dll, state, '%s', count(*) FROM function GROUP BY dll, state",
1294 &szCurDt[0]);
1295 rc = mysql_query(pmysql, pszQuery);
1296 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1297
1298 sprintf(pszQuery, "INSERT INTO historyapigroup(apigroup, state, date, count) "
1299 "SELECT dll, state, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
1300 "GROUP BY apigroup, state",
1301 &szCurDt[0]);
1302 rc = mysql_query(pmysql, pszQuery);
1303 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1304
1305 /* inserting new totals */
1306 sprintf(pszQuery, "INSERT INTO historydlltotal(dll, date, totalcount) "
1307 "SELECT dll, '%s', count(*) FROM function GROUP BY dll",
1308 &szCurDt[0]);
1309 rc = mysql_query(pmysql, pszQuery);
1310 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1311
1312 sprintf(pszQuery, "INSERT INTO historyapigrouptotal(apigroup, date, totalcount) "
1313 "SELECT apigroup, '%s', count(*) FROM function WHERE apigroup IS NOT NULL "
1314 "GROUP BY apigroup",
1315 &szCurDt[0]);
1316 rc = mysql_query(pmysql, pszQuery);
1317 CheckLogContinue((pszError, "error inserting: %s - (sql=%s) ", dbGetLastErrorDesc(), pszQuery));
1318 }
1319 else
1320 {
1321 sprintf(pszError, "error getting current date (row == NULL): %s - (sql=%s) ",
1322 dbGetLastErrorDesc(), pszQuery);
1323 ulRc++;
1324 }
1325 }
1326 else
1327 {
1328 sprintf(pszError, "error getting current date: %s - (sql=%s) ",
1329 dbGetLastErrorDesc(), pszQuery);
1330 ulRc++;
1331 }
1332
1333 mysql_refresh(pmysql, REFRESH_TABLES);
1334
1335 return ulRc;
1336}
1337
1338
1339/**
1340 * Check that database integrety is ok. Verfies foreign keys.
1341 * @returns numbers of errors.
1342 * @param pszError Very large buffer which will hold error messges (if any).
1343 * @sketch
1344 * @remark current versions of mysql don't support 'SELECT ... WHERE id NOT IN(SELECT id FROM table)'
1345 */
1346unsigned long _System dbCheckIntegrity(char *pszError)
1347{
1348 char szQuery[384];
1349 char *pszQuery = &szQuery[0];
1350 MYSQL_RES *pres1;
1351 MYSQL_RES *pres2;
1352 MYSQL_ROW row1;
1353 int rc;
1354 unsigned long ulRc = 0;
1355
1356 mysql_refresh(pmysql, REFRESH_TABLES);
1357
1358 /* foreign keys in function table */
1359 strcpy(pszQuery, "SELECT refcode, dll, state, apigroup, file FROM function");
1360 rc = mysql_query(pmysql, pszQuery);
1361 if (rc >= 0)
1362 {
1363 pres1 = mysql_store_result(pmysql);
1364 if (pres1 != NULL)
1365 {
1366 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1367 {
1368 /* check dll */
1369 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1370 rc = mysql_query(pmysql, pszQuery);
1371 CheckFKError("function/dll", "Foreign key 'dll' not found in the dll table");
1372
1373 /* check state */
1374 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1375 rc = mysql_query(pmysql, pszQuery);
1376 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1377
1378 /* check apigroup */
1379 if (row1[3] != NULL)
1380 {
1381 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[3]);
1382 rc = mysql_query(pmysql, pszQuery);
1383 CheckFKError("function/state", "Foreign key 'state' not found in the state table");
1384 }
1385
1386 /* check file */
1387 if (atoi(row1[4]) >= 0)
1388 {
1389 sprintf(pszQuery, "SELECT refcode FROM file WHERE refcode = %s", row1[4]);
1390 rc = mysql_query(pmysql, pszQuery);
1391 CheckFKError("function/file", "Foreign key 'file' not found in the file table");
1392 }
1393 }
1394 mysql_free_result(pres1);
1395 }
1396 }
1397 else
1398 ulRc += logDbError(pszError, pszQuery);
1399
1400 /* foreign keys in file */
1401 strcpy(pszQuery, "SELECT refcode, dll FROM file");
1402 rc = mysql_query(pmysql, pszQuery);
1403 if (rc >= 0)
1404 {
1405 pres1 = mysql_store_result(pmysql);
1406 if (pres1 != NULL)
1407 {
1408 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1409 {
1410 /* check dll */
1411 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1412 rc = mysql_query(pmysql, pszQuery);
1413 CheckFKError("apigroup/dll", "Foreign key 'dll' not found in the dll table");
1414 }
1415 mysql_free_result(pres1);
1416 }
1417 }
1418 else
1419 ulRc += logDbError(pszError, pszQuery);
1420
1421 /* foreign keys in apigroup */
1422 strcpy(pszQuery, "SELECT refcode, dll FROM apigroup");
1423 rc = mysql_query(pmysql, pszQuery);
1424 if (rc >= 0)
1425 {
1426 pres1 = mysql_store_result(pmysql);
1427 if (pres1 != NULL)
1428 {
1429 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1430 {
1431 /* check dll */
1432 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1433 rc = mysql_query(pmysql, pszQuery);
1434 CheckFKError("file/dll", "Foreign key 'dll' not found in the dll table");
1435 }
1436 mysql_free_result(pres1);
1437 }
1438 }
1439 else
1440 ulRc += logDbError(pszError, pszQuery);
1441
1442 /* foreign keys in fnauthor */
1443 strcpy(pszQuery, "SELECT function, author FROM fnauthor");
1444 rc = mysql_query(pmysql, pszQuery);
1445 if (rc >= 0)
1446 {
1447 pres1 = mysql_store_result(pmysql);
1448 if (pres1 != NULL)
1449 {
1450 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1451 {
1452 /* check function */
1453 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1454 rc = mysql_query(pmysql, pszQuery);
1455 CheckFKError("fnauthor/function", "Foreign key 'function' not found in the function table");
1456
1457 /* check author */
1458 sprintf(pszQuery, "SELECT refcode FROM author WHERE refcode = %s", row1[1]);
1459 rc = mysql_query(pmysql, pszQuery);
1460 CheckFKError("fnauthor/author", "Foreign key 'author' not found in the author table");
1461 }
1462 mysql_free_result(pres1);
1463 }
1464 }
1465 else
1466 ulRc += logDbError(pszError, pszQuery);
1467
1468 /* foreign keys in historydll table */
1469 strcpy(pszQuery, "SELECT date, dll, state FROM historydll");
1470 rc = mysql_query(pmysql, pszQuery);
1471 if (rc >= 0)
1472 {
1473 pres1 = mysql_store_result(pmysql);
1474 if (pres1 != NULL)
1475 {
1476 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1477 {
1478 /* check dll */
1479 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1480 rc = mysql_query(pmysql, pszQuery);
1481 CheckFKError("historydll/dll", "Foreign key 'dll' not found in the dll table");
1482
1483 /* check state */
1484 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1485 rc = mysql_query(pmysql, pszQuery);
1486 CheckFKError("historydll/state", "Foreign key 'state' not found in the state table");
1487 }
1488 mysql_free_result(pres1);
1489 }
1490 }
1491 else
1492 ulRc += logDbError(pszError, pszQuery);
1493
1494 /* foreign keys in historyapigroup table */
1495 strcpy(pszQuery, "SELECT date, apigroup, state FROM historyapigroup");
1496 rc = mysql_query(pmysql, pszQuery);
1497 if (rc >= 0)
1498 {
1499 pres1 = mysql_store_result(pmysql);
1500 if (pres1 != NULL)
1501 {
1502 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1503 {
1504 /* check dll */
1505 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1506 rc = mysql_query(pmysql, pszQuery);
1507 CheckFKError("historyapigroup/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1508
1509 /* check state */
1510 sprintf(pszQuery, "SELECT refcode FROM state WHERE refcode = %s", row1[2]);
1511 rc = mysql_query(pmysql, pszQuery);
1512 CheckFKError("historyapigroup/state", "Foreign key 'state' not found in the state table");
1513 }
1514 mysql_free_result(pres1);
1515 }
1516 }
1517 else
1518 ulRc += logDbError(pszError, pszQuery);
1519
1520 /* foreign keys in historydlltotal table */
1521 strcpy(pszQuery, "SELECT date, dll FROM historydlltotal");
1522 rc = mysql_query(pmysql, pszQuery);
1523 if (rc >= 0)
1524 {
1525 pres1 = mysql_store_result(pmysql);
1526 if (pres1 != NULL)
1527 {
1528 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1529 {
1530 /* check dll */
1531 sprintf(pszQuery, "SELECT refcode FROM dll WHERE refcode = %s", row1[1]);
1532 rc = mysql_query(pmysql, pszQuery);
1533 CheckFKError("historydlltotal/dll", "Foreign key 'dll' not found in the dll table");
1534 }
1535 mysql_free_result(pres1);
1536 }
1537 }
1538 else
1539 ulRc += logDbError(pszError, pszQuery);
1540
1541 /* foreign keys in historyapigroup table */
1542 strcpy(pszQuery, "SELECT date, apigroup FROM historyapigrouptotal");
1543 rc = mysql_query(pmysql, pszQuery);
1544 if (rc >= 0)
1545 {
1546 pres1 = mysql_store_result(pmysql);
1547 if (pres1 != NULL)
1548 {
1549 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1550 {
1551 /* check dll */
1552 sprintf(pszQuery, "SELECT refcode FROM apigroup WHERE refcode = %s", row1[1]);
1553 rc = mysql_query(pmysql, pszQuery);
1554 CheckFKError("historyapigrouptotal/apigroup", "Foreign key 'apigroup' not found in the apigroup table");
1555 }
1556 mysql_free_result(pres1);
1557 }
1558 }
1559 else
1560 ulRc += logDbError(pszError, pszQuery);
1561
1562 /* foreign keys in parameter table */
1563 strcpy(pszQuery, "SELECT sequencenbr, function FROM parameter");
1564 rc = mysql_query(pmysql, pszQuery);
1565 if (rc >= 0)
1566 {
1567 pres1 = mysql_store_result(pmysql);
1568 if (pres1 != NULL)
1569 {
1570 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1571 {
1572 /* check function */
1573 sprintf(pszQuery, "SELECT refcode FROM function WHERE refcode = %s", row1[1]);
1574 rc = mysql_query(pmysql, pszQuery);
1575 CheckFKError("parameter/function", "Foreign key 'function' not found in the function table");
1576 }
1577 mysql_free_result(pres1);
1578 }
1579 }
1580 else
1581 ulRc += logDbError(pszError, pszQuery);
1582
1583 /* Author table is special, since you should be able to interchangably reference an
1584 * author by any of the following tables:
1585 * name
1586 * initials
1587 * alias
1588 * email
1589 */
1590 strcpy(pszQuery, "SELECT name, initials, alias, email FROM author");
1591 rc = mysql_query(pmysql, pszQuery);
1592 if (rc >= 0)
1593 {
1594 pres1 = mysql_store_result(pmysql);
1595 if (pres1 != NULL)
1596 {
1597 while ((row1 = mysql_fetch_row(pres1)) != NULL)
1598 {
1599 /* check name */
1600 sprintf(pszQuery, "SELECT name FROM author WHERE "
1601 "initials = '%s' OR alias = '%s' OR email = '%s'",
1602 row1[0], row1[0], row1[0]);
1603 ulRc += CheckAuthorError(pszError, "name", row1[0], pszQuery);
1604
1605 /* check initials */
1606 sprintf(pszQuery, "SELECT name FROM author WHERE "
1607 "alias = '%s' OR email = '%s'",
1608 row1[1], row1[1]);
1609 ulRc += CheckAuthorError(pszError, "initials", row1[1], pszQuery);
1610
1611 /* alias */
1612 if (row1[2] != NULL)
1613 {
1614 sprintf(pszQuery, "SELECT name FROM author WHERE "
1615 "email = '%s'",
1616 row1[2]);
1617 ulRc += CheckAuthorError(pszError, "alias", row1[2], pszQuery);
1618 }
1619 }
1620 mysql_free_result(pres1);
1621 }
1622 }
1623 else
1624 ulRc += logDbError(pszError, pszQuery);
1625
1626 return ulRc;
1627}
1628
1629
1630/**
1631 * Checks for duplicate key and sql error for a given author key in the author table... (arg!)
1632 * @returns Number of errors.
1633 * @param pszError Reference to error buffer pointer.
1634 * @param pszFieldName Key field name; used for logging.
1635 * @param pszFieldValue Key value; used for logging
1636 * @param pszQuery Query which is to be exectued to test for duplicate key.
1637 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1638 */
1639static unsigned long CheckAuthorError(char * &pszError, const char *pszFieldName, const char *pszFieldValue, const char *pszQuery)
1640{
1641 MYSQL_ROW row;
1642 MYSQL_RES *pres;
1643 unsigned long ulRc = 0;
1644 int rc;
1645
1646 rc = mysql_query(pmysql, pszQuery);
1647 pres = mysql_store_result(pmysql);
1648 if (rc < 0 || (pres != NULL && mysql_num_rows(pres) != 0))
1649 { /* some kind of error has occurred */
1650 if (pszError[1] == '\xFE')
1651 {
1652 strcat(pszError, "\n\t");
1653 pszError += 2;
1654 }
1655
1656 if (rc < 0) /* sql error or 'duplicate key' */
1657 {
1658 sprintf(pszError, "author/%s: select failed - %s (sql=%s)",
1659 pszFieldName, dbGetLastErrorDesc(), pszQuery);
1660 }
1661 else
1662 { /* 'duplicate key' - print duplicates */
1663 sprintf(pszError, "author/%s: 'duplicate key', %s='%s': ",
1664 pszFieldName, pszFieldValue, pszFieldName);
1665
1666 while ((row = mysql_fetch_row(pres)) != NULL)
1667 {
1668 pszError += strlen(pszError);
1669 sprintf(pszError, "'%s' ", row[0]);
1670 }
1671 }
1672
1673 pszError += strlen(pszError);
1674 pszError[1] = '\xFE';
1675 ulRc = 1;
1676 }
1677 if (pres != NULL)
1678 mysql_free_result(pres);
1679
1680 return ulRc;
1681}
1682
1683
1684/**
1685 * Writes db error (rc<0) to the log buffer.
1686 * @returns Number of signals.
1687 * @param pszError Reference to the error buffer pointer.
1688 * @param pszQuery Pointer to query which was executed.
1689 * @remark Uses pszError[1] == '\xFE' to detect when to insert '\n\t'.
1690 */
1691static unsigned long logDbError(char * &pszError, const char *pszQuery)
1692{
1693 if (pszError[1] == '\xFE')
1694 {
1695 strcat(pszError, "\n\t");
1696 pszError += 2;
1697 }
1698 sprintf(pszError, "select failed: %s - (sql=%s)", dbGetLastErrorDesc(), pszQuery);
1699
1700 pszError += strlen(pszError);
1701 pszError[1] = '\xFE';
1702
1703 return 1;
1704}
1705
1706
1707/**
1708 * Executes a give query and returns a result identifier/pointer.
1709 * @returns Query result identifier/pointer. NULL on error.
1710 * @param pszQuery Pointer to query.
1711 * @remark Used by and designed for kHtmlPC.
1712 */
1713void * _System dbExecuteQuery(const char *pszQuery)
1714{
1715 assert(pmysql != NULL);
1716 if (mysql_query(pmysql, pszQuery) >= 0)
1717 return mysql_store_result(pmysql);
1718
1719 return NULL;
1720}
1721
1722
1723/**
1724 * Asks for the number of rows in the result.
1725 * @returns Number of rows in the result. -1 on error.
1726 * @param pres Query result identifier/pointer.
1727 * @remark Used by and designed for kHtmlPC.
1728 */
1729signed long _System dbQueryResultRows(void *pres)
1730{
1731 if (pres == NULL)
1732 return -1;
1733 return mysql_num_rows((MYSQL_RES*)pres);
1734}
1735
1736
1737/**
1738 * Frees the storage allocated by the given result.
1739 * @returns Success indicator, TRUE/FALSE.
1740 * @param pres Query result identifier/pointer.
1741 * @remark Used by and designed for kHtmlPC.
1742 */
1743BOOL _System dbFreeResult(void *pres)
1744{
1745 if (pres != NULL)
1746 mysql_free_result((MYSQL_RES*)pres);
1747 else
1748 return FALSE;
1749 return TRUE;
1750}
1751
1752
1753/**
1754 * Fetch data from a result. Returns the data by calling the given callback function.
1755 * @returns Success indicator, TRUE/FALSE.
1756 * @param pres Query result identifier/pointer.
1757 * @param dbFetchCallBack Callback-function.
1758 * @param pvUser User parameter which is passed onto dbFetchCallBack.
1759 * @remark Used by and designed for kHtmlPC.
1760 */
1761BOOL _System dbFetch(void *pres, DBCALLBACKFETCH dbFetchCallBack, void *pvUser)
1762{
1763 BOOL fRc = FALSE;
1764 MYSQL_ROW row = mysql_fetch_row((MYSQL_RES*)pres);
1765
1766 if (row)
1767 {
1768 MYSQL_FIELD *pField;
1769 int i = 0;
1770 mysql_field_seek((MYSQL_RES*)pres, 0);
1771
1772 while ((pField = mysql_fetch_field((MYSQL_RES*)pres)) != NULL)
1773 if (dbFetchCallBack(row[i++], pField->name, pvUser) != 0)
1774 return FALSE;
1775
1776 fRc = TRUE;
1777 }
1778
1779 return fRc;
1780}
1781
1782
1783/**
1784 * Converts an ISO date to days after Christ, year 0.
1785 * @returns days. -1 on error;
1786 * @param pszDate ISO Date.
1787 */
1788signed long _System dbDateToDaysAfterChrist(const char *pszDate)
1789{
1790 signed long lRet = -1;
1791 char szQuery[128];
1792
1793 sprintf(&szQuery[0], "SELECT to_days('%s')", pszDate);
1794 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1795 {
1796 MYSQL_ROW row;
1797 MYSQL_RES *pres = mysql_use_result(pmysql);
1798 row = mysql_fetch_row(pres);
1799 if (row != NULL)
1800 {
1801 lRet = atol(row[0]);
1802 do { row = mysql_fetch_row(pres); } while (row != NULL);
1803 }
1804 }
1805
1806 return lRet;
1807}
1808
1809
1810/**
1811 * Converts days after Christ (year 0) to ISO date.
1812 * @returns Success indicator. TRUE/FALSE;
1813 * @param lDays Days after Christ (year 0).
1814 * @param pszDate ISO Date. Result.
1815 */
1816BOOL _System dbDaysAfterChristToDate(signed long lDays, char *pszDate)
1817{
1818 BOOL fRet = FALSE;
1819 char szQuery[128];
1820
1821 if (lDays < 0)
1822 return FALSE;
1823
1824 sprintf(&szQuery[0], "SELECT from_days(%ld)", lDays);
1825 if (mysql_query(pmysql, &szQuery[0]) >= 0)
1826 {
1827 MYSQL_ROW row;
1828 MYSQL_RES *pres = mysql_use_result(pmysql);
1829 row = mysql_fetch_row(pres);
1830 if (row != NULL)
1831 {
1832 fRet = strlen(row[0]) == (4+1+2+1+2) && row[0][4] == '-' && row[0][7] == '-'
1833 && strcmp(row[0], "0000-00-00") != 0;
1834 if (fRet)
1835 strcpy(pszDate, row[0]);
1836 do { row = mysql_fetch_row(pres); } while (row != NULL);
1837 }
1838 }
1839
1840 return fRet;
1841}
1842
1843
1844/**
1845 * Display all functions for, the given dll, that is not updated.
1846 * @returns TRUE / FALSE.
1847 * @param lDll Dll reference number.
1848 * @param dbFetchCall Callback function which will be called once for each
1849 * field for all the functions not updated.
1850 * pvUser is NULL, pszValue field value, pszFieldName the field name.
1851 */
1852BOOL _System dbGetNotUpdatedFunction(signed long lDll, DBCALLBACKFETCH dbFetchCallBack)
1853{
1854 BOOL fRet = FALSE;
1855 void *pres;
1856 char szQuery[256];
1857
1858 /* not updated names */
1859 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1860 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1861 " LEFT JOIN dll d ON f2.dll = d.refcode "
1862 "WHERE f1.dll = %ld AND f1.updated = 0",
1863 lDll);
1864 pres = dbExecuteQuery(szQuery);
1865 if (pres != NULL)
1866 {
1867 BOOL f;
1868 do
1869 {
1870 f = dbFetch(pres, dbFetchCallBack, NULL);
1871 } while (f);
1872 dbFreeResult(pres);
1873 fRet = TRUE;
1874 }
1875
1876 /* warn about updated > 1 too */
1877 sprintf(&szQuery[0], "SELECT f1.name, f1.intname, f1.updated, f1.aliasfn, d.name, f2.name, f2.intname AS last "
1878 "FROM function f1 LEFT OUTER JOIN function f2 ON f1.aliasfn = f2.refcode "
1879 " LEFT JOIN dll d ON f2.dll = d.refcode "
1880 "WHERE f1.dll = %ld AND f1.updated > 1",
1881 lDll);
1882 pres = dbExecuteQuery(szQuery);
1883 if (pres != NULL)
1884 {
1885 BOOL f;
1886 do
1887 {
1888 f = dbFetch(pres, dbFetchCallBack, NULL);
1889 } while (f);
1890 dbFreeResult(pres);
1891 fRet = TRUE;
1892 }
1893
1894 strcpy(&szQuery[0], "UPDATE function SET updated = 0");
1895 mysql_query(pmysql, &szQuery[0]);
1896
1897 return fRet;
1898}
1899
1900
1901/**
1902 * Counts the function for the given DLL which has been updated.
1903 * @returns -1 on error, number of updated function on success.
1904 * @param lDll Dll reference number.
1905 */
1906signed long _System dbGetNumberOfUpdatedFunction(signed long lDll)
1907{
1908 int rc;
1909 char szQuery[128];
1910 MYSQL_RES * pres;
1911
1912 sprintf(&szQuery[0], "SELECT count(*) FROM function WHERE dll = (%ld) AND updated > 0\n", lDll);
1913 rc = mysql_query(pmysql, &szQuery[0]);
1914 pres = mysql_store_result(pmysql);
1915 if (rc >= 0 && pres != NULL && mysql_num_rows(pres) == 1)
1916 rc = (int)getvalue(0, mysql_fetch_row(pres));
1917 else
1918 rc = -1;
1919 mysql_free_result(pres);
1920 return (signed long)rc;
1921}
1922
1923
1924
1925/**
1926 * Clear the update flags for all file in a dll/module.
1927 * @returns Success indicator. (TRUE / FALSE)
1928 * @param lDll Dll refcode.
1929 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1930 * @remark Intended for use by APIImport.
1931 */
1932BOOL _System dbClearUpdateFlagFile(signed long lDll)
1933{
1934 int rc;
1935 char szQuery[128];
1936
1937 sprintf(&szQuery[0],
1938 "UPDATE file SET updated = 0 WHERE dll = (%ld)",
1939 lDll);
1940 rc = mysql_query(pmysql, &szQuery[0]);
1941 return rc == 0;
1942}
1943
1944
1945/**
1946 * Clear update flag
1947 * @returns Success indicator.
1948 * @param lDll Dll refcode.
1949 * @param fAll All dll. If false only APIs and Internal APIs are cleared
1950 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1951 * @remark Intended for use by APIImport.
1952 */
1953BOOL _System dbClearUpdateFlagFunction(signed long lDll, BOOL fAll)
1954{
1955 int rc;
1956 char szQuery[128];
1957
1958 sprintf(&szQuery[0],
1959 "UPDATE function SET updated = 0 WHERE dll = (%ld)",
1960 lDll);
1961 if (!fAll)
1962 strcat(&szQuery[0], " AND type IN ('A', 'I')");
1963 rc = mysql_query(pmysql, &szQuery[0]);
1964 return rc == 0;
1965}
1966
1967
1968
1969/**
1970 * Deletes all the files in a dll/module which was not found/updated.
1971 * @returns Success indicator.
1972 * @param lDll Dll refcode.
1973 * @sketch Select all files which is to be deleted.
1974 * Set all references to each file in function to -1.
1975 * Delete all files which is to be deleted.
1976 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
1977 * @remark Use with GRATE CARE!
1978 */
1979BOOL _System dbDeleteNotUpdatedFiles(signed long lDll)
1980{
1981 MYSQL_RES * pres;
1982 int rc;
1983 BOOL fRc = TRUE;
1984 char szQuery[128];
1985
1986 sprintf(&szQuery[0],
1987 "SELECT refcode FROM file WHERE dll = (%ld) AND updated = 0",
1988 lDll);
1989 rc = mysql_query(pmysql, &szQuery[0]);
1990 pres = mysql_store_result(pmysql);
1991 if (pres != NULL && mysql_num_rows(pres))
1992 {
1993 MYSQL_ROW row;
1994 while ((row = mysql_fetch_row(pres)) != NULL)
1995 {
1996 sprintf(&szQuery[0],
1997 "UPDATE function SET file = -1 WHERE file = %s",
1998 row[0]);
1999 rc = mysql_query(pmysql, &szQuery[0]);
2000 if (rc) fRc = FALSE;
2001 }
2002 }
2003
2004 sprintf(&szQuery[0],
2005 "DELETE FROM file WHERE dll = %ld AND updated = 0",
2006 lDll);
2007 rc = mysql_query(pmysql, &szQuery[0]);
2008 if (rc) fRc = FALSE;
2009
2010 return fRc;
2011}
2012
2013
2014/**
2015 * Deletes all the functions which haven't been updated.
2016 * All rows in other tables which references the functions are
2017 * also delete.
2018 *
2019 * @returns Success indicator. (TRUE / FALSE)
2020 * @param lDll The refcode of the dll owning the functions.
2021 * @param fAll All function. If FALSE then only APIs and Internal APIs.
2022 * @sketch Select all functions which has updated = 0 and dll = lDll.
2023 * Delete the referenced to the functions in:
2024 * parameters
2025 * fnauthor
2026 * Delete all function which has updated = 0 and dll = lDll
2027 *
2028 * @remark Use with GREATE CARE!
2029 */
2030BOOL _System dbDeleteNotUpdatedFunctions(signed long lDll, BOOL fAll)
2031{
2032 MYSQL_RES * pres;
2033 int rc;
2034 BOOL fRc = TRUE;
2035 char szQuery[128];
2036
2037 sprintf(&szQuery[0],
2038 "SELECT refcode FROM function WHERE dll = %ld AND updated = 0",
2039 lDll);
2040 if (!fAll)
2041 strcat(&szQuery[0], " AND type IN ('A', 'I')");
2042 rc = mysql_query(pmysql, &szQuery[0]);
2043 pres = mysql_store_result(pmysql);
2044 if (pres != NULL && mysql_num_rows(pres))
2045 {
2046 MYSQL_ROW row;
2047 while ((row = mysql_fetch_row(pres)) != NULL)
2048 {
2049 /* delete parameters */
2050 sprintf(&szQuery[0], "DELETE FROM parameter WHERE function %s", row[0]);
2051 rc = mysql_query(pmysql, &szQuery[0]);
2052 if (rc) fRc = FALSE;
2053
2054 /* author relations */
2055 sprintf(&szQuery[0], "DELETE FROM fnauthor WHERE function %s", row[0]);
2056 rc = mysql_query(pmysql, &szQuery[0]);
2057 if (rc) fRc = FALSE;
2058 }
2059 }
2060
2061 sprintf(&szQuery[0],
2062 "DELETE FROM function WHERE dll = %ld AND updated = 0",
2063 lDll);
2064 if (!fAll)
2065 strcat(&szQuery[0], " AND type IN ('A', 'I')");
2066 rc = mysql_query(pmysql, &szQuery[0]);
2067 if (rc) fRc = FALSE;
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.