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

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

Added call to mysql_init before connect.

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