submitting patch from enterprise version
[csql.git] / src / storage / Config.cxx
blob6ff154c48e4d65dc7b741d3cb3a72057945e9fb9
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 ***************************************************************************/
16 #include<Config.h>
17 #include<ErrorType.h>
18 #include<Debug.h>
20 Config Conf::config;
22 int Config::readLine(FILE *fp, char * buffer)
24 char c =0;
25 int count =0;
26 while (true)
28 c = fgetc(fp);
29 if (c == '\n') break;
30 if (c == EOF) return EOF;
31 buffer[count++] = c;
33 return count;
35 int Config::storeKeyVal(char *key, char *value)
37 if (os::os::strcasestr(key, "PAGE_SIZE") != NULL )
38 { cVal.pageSize = atoi(value); }
39 else if (os::strcasestr(key, "MAX_PROCS") != NULL)
40 { cVal.maxProcs = atoi(value); }
41 else if (os::strcasestr(key, "MAX_SYS_DB_SIZE") != NULL)
42 { cVal.maxSysSize = atol(value); }
43 else if (os::strcasestr(key, "MAX_DB_SIZE") != NULL)
44 { cVal.maxDbSize = atol(value); }
45 else if (os::strcasestr(key, "MMAP") != NULL)
46 { cVal.mmap = os::atobool(value); }
47 else if (os::strcasestr(key, "SYS_DB_KEY") != NULL)
48 { cVal.sysDbKey = atoi(value); }
49 else if (os::strcasestr(key, "USER_DB_KEY") != NULL)
50 { cVal.userDbKey = atoi(value); }
51 else if (os::strcasestr(key, "LOG_FILE") != NULL)
52 { strcpy(cVal.logFile , value); }
53 else if (os::strcasestr(key, "DATABASE_FILE") != NULL)
54 { strcpy(cVal.dbFile , value); }
55 else if (os::strcasestr(key, "MAP_ADDRESS") != NULL)
56 { cVal.mapAddr = atol(value); }
57 else if (os::strcasestr(key, "MUTEX_TIMEOUT_SECS") != NULL)
58 { cVal.mutexSecs = atoi(value); }
59 else if (os::strcasestr(key, "MUTEX_TIMEOUT_USECS") != NULL)
60 { cVal.mutexUSecs = atoi(value); }
61 else if (os::strcasestr(key, "MUTEX_TIMEOUT_RETRIES") != NULL)
62 { cVal.mutexRetries = atoi(value); }
63 else if (os::strcasestr(key, "LOCK_TIMEOUT_SECS") != NULL)
64 { cVal.lockSecs = atoi(value); }
65 else if (os::strcasestr(key, "LOCK_TIMEOUT_USECS") != NULL)
66 { cVal.lockUSecs = atoi(value); }
67 else if (os::strcasestr(key, "LOCK_TIMEOUT_RETRIES") != NULL)
68 { cVal.lockRetries = atoi(value); }
69 else if (os::strcasestr(key, "LOG_LEVEL") != NULL)
70 { cVal.logLevel = atoi(value); }
71 else if (os::strcasestr(key, "DSN") != NULL)
72 { strcpy(cVal.dsn , value); }
73 else if (os::strcasestr(key,"DS_CONFIG_FILE") !=NULL)
74 { strcpy(cVal.dsConfigFile,value);}
75 else if (os::strcasestr(key, "TABLE_CONFIG_FILE") != NULL)
76 { strcpy(cVal.tableConfigFile , value); }
77 else if (os::strcasestr(key, "STDERR_FILE") != NULL)
78 { strcpy(cVal.stderrFile, value); }
79 else if (os::strcasestr(key, "CONFL_RESOL_FILE") != NULL)
80 { strcpy(cVal.conflResoFile , value); }
81 else if (os::strcasestr(key, "CACHE_TABLE") != NULL)
82 { cVal.isCache = os::atobool(value); }
83 else if (os::strcasestr(key, "CACHE_MODE") != NULL)
85 if (strcmp(value, "SYNC") == 0)
86 { cVal.mode = SYNC_MODE; }
87 else if (strcmp(value, "ASYNC") == 0)
88 { cVal.mode = ASYNC_MODE; }
89 else cVal.mode = UNKNOWN;
91 else if(os::strcasestr(key,"SITE_ID")!=NULL)
92 { cVal.siteID = atoi(value);}
93 else if(os::strcasestr(key,"REPLICATION_SITES")!=NULL)
94 { cVal.maxReplSites = atoi(value);}
95 else if (os::strcasestr(key, "REPLICATION") != NULL)
96 { cVal.isReplication = os::atobool(value); }
97 else if (os::strcasestr(key, "DURABILITY") != NULL)
98 { cVal.isDurable = os::atobool(value); }
99 else if (os::strcasestr(key, "DURABLE_MODE") != NULL)
100 { cVal.durableMode = ::atoi(value); }
101 else if (os::strcasestr(key, "CSQL_SQL_SERVER") != NULL)
102 { cVal.isCsqlSqlServer = os::atobool(value); }
103 else if (os::strcasestr(key, "PORT") != NULL)
104 { cVal.port = atoi(value); }
105 else if (os::strcasestr(key, "NETWORK_CONFIG_FILE") != NULL)
106 { strcpy(cVal.replConfigFile , value); }
107 else if (os::strcasestr(key, "MAX_QUEUE_LOGS") != NULL)
108 { cVal.maxQueueLogs = atol(value); }
109 else if (os::strcasestr(key, "MSG_KEY") != NULL)
110 { cVal.msgKey = atoi(value); }
111 else if (os::strcasestr(key, "ASYNC_MSGMAX") != NULL)
112 { cVal.asyncMsgMax = atoi(value); }
113 else if (os::strcasestr(key, "ID_SHM_KEY") != NULL)
114 { cVal.shmKeyForId = atoi(value); }
115 else if (os::strcasestr(key, "NETWORK_RESPONSE_TIMEOUT") != NULL)
116 { cVal.nwResponseTimeout = atoi(value); }
117 else if (os::strcasestr(key, "NETWORK_CONNECT_TIMEOUT") != NULL)
118 { cVal.nwConnectTimeout = atoi(value); }
119 else if (os::strcasestr(key, "ENABLE_BIDIRECTIONAL_CACHE") != NULL)
120 { cVal.isTwoWay = os::atobool(value); }
121 else if (os::strcasestr(key, "CACHE_RECEIVER_WAIT_SECS") != NULL)
122 { cVal.cacheWaitSecs = atoi(value); }
123 else return 1;
124 return 0;
126 int Config::validateValues()
128 if (cVal.pageSize < 8192 || cVal.pageSize > 1024 * 1024 * 10 )
130 printError(ErrBadArg, "PAGE_SIZE should be >= 8192 and <= 10 MB");
131 return 1;
133 if (cVal.pageSize % 1024 !=0 )
135 printError(ErrBadArg, "PAGE_SIZE should be multiples of 1024");
136 return 1;
138 #if (defined TRIAL) || (defined BASIC)
139 if (cVal.maxProcs < 1 || cVal.maxProcs > 5)
141 printf("Trial license supports only 5 connections");
142 printf("Contact sales@csqldb.com to get full license");
143 return 1;
145 #else
146 if (cVal.maxProcs < 10 || cVal.maxProcs > 8192)
148 printError(ErrBadArg, "MAX_PROCS should be >= 10 and <= 8192");
149 return 1;
151 #endif
152 if (cVal.maxSysSize < 1024 * 1024 || cVal.maxSysSize > 1024 *1024 *1024)
154 printError(ErrBadArg, "MAX_SYS_DB_SIZE should be >= 1 MB and <= 1 GB");
155 return 1;
157 if (cVal.maxSysSize % 8192 !=0 )
159 printError(ErrBadArg, "MAX_SYS_DB_SIZE should be multiples of 8192");
160 return 1;
163 #ifdef TRIAL
164 if (cVal.maxDbSize < 1024 * 1024 || cVal.maxDbSize > (20 * 1024*1024))
166 printf("Trial license supports only 20 MB db size");
167 printf("Contact sales@csqldb.com to get full license");
168 return 1;
170 #else
171 #ifdef BASIC
172 if (cVal.maxDbSize < 1024 * 1024 || cVal.maxDbSize > (100 * 1024*1024))
174 printf("Basic subscription supports only 100 MB db size");
175 printf("Contact sales@csqldb.com to upgrade");
176 return 1;
179 #else
180 #ifdef x86_64
181 if (cVal.maxDbSize < 1024 * 1024 || cVal.maxDbSize > ( 100*1024*1024*1024L))
183 printError(ErrBadArg, "MAX_DB_SIZE should be >= 1 MB and <= 100 GB");
184 return 1;
186 #else
187 unsigned long maxVal = 2*1024*1024*1024L;
188 if (cVal.maxDbSize < 1024 * 1024 || ((unsigned long)cVal.maxDbSize) > maxVal)
190 printError(ErrBadArg, "MAX_DB_SIZE should be >= 1 MB and <= 2 GB");
191 return 1;
193 #endif
194 #endif
195 #endif
196 if (cVal.maxDbSize % 8192 !=0)
198 printError(ErrBadArg, "MAX_DB_SIZE should be multiples of 8192");
199 return 1;
202 if (cVal.sysDbKey < 10 || cVal.sysDbKey > 8192)
204 printError(ErrBadArg, "SYS_DB_KEY should be >= 10 and <= 8192");
205 return 1;
207 if (cVal.userDbKey < 10 || cVal.userDbKey > 8192)
209 printError(ErrBadArg, "USER_DB_KEY should be >= 10 and <= 8192");
210 return 1;
212 if ( cVal.sysDbKey == cVal.userDbKey)
214 printError(ErrBadArg, "USER_DB_KEY and SYS_DB_KEY have same value %d", cVal.userDbKey);
215 return 1;
217 if (0 == strcmp(cVal.logFile,""))
219 //TODO::check whether file exists
220 printError(ErrBadArg, "LOG_FILE is set to NULL");
221 return 1;
223 if (0 == strcmp(cVal.dbFile,""))
225 printError(ErrBadArg, "LOG_FILE is set to NULL");
226 return 1;
228 if (cVal.mapAddr < 400000000 || cVal.mapAddr > 2000000000)
230 printError(ErrBadArg, "MAP_ADDRESS should be >= 400000000 and <= 2000000000");
231 return 1;
233 if (cVal.mutexSecs < 0 || cVal.mutexSecs > 360)
235 printError(ErrBadArg, "MUTEX_TIMEOUT_SECS should be >= 0 and <= 360");
236 return 1;
238 if (cVal.mutexUSecs < 0 || cVal.mutexUSecs > 1000000)
240 printError(ErrBadArg, "MUTEX_TIMEOUT_USECS should be >= 0 and <= 1000000");
241 return 1;
243 if (cVal.mutexRetries < 0 || cVal.mutexRetries > 100)
245 printError(ErrBadArg, "MUTEX_TIMEOUT_RETRY should be >= 0 and <= 100");
246 return 1;
248 if (cVal.lockSecs < 0 || cVal.lockSecs > 360)
250 printError(ErrBadArg, "LOCK_TIMEOUT_SECS should be >= 0 and <= 360");
251 return 1;
253 if (cVal.lockUSecs < 0 || cVal.lockUSecs > 1000000)
255 printError(ErrBadArg, "LOCK_TIMEOUT_USECS should be >= 0 and <= 1000000");
256 return 1;
258 if (cVal.lockRetries < 0 || cVal.lockRetries > 100)
260 printError(ErrBadArg, "LOCK_TIMEOUT_RETRY should be >= 0 and <= 100");
261 return 1;
263 if (cVal.logLevel < 0 || cVal.logLevel > 3)
265 printError(ErrBadArg, "LOG_LEVEL should be >= 0 and <= 3");
266 return 1;
268 #ifdef NOREPL
269 if (cVal.isReplication) {
270 printf("This version does not support replication.\n");
271 printf("Please contact sales@csqldb.com to upgrade\n");
272 return 1;
274 #endif
275 /* if (cVal.isCache && cVal.isReplication) {
276 printError(ErrBadArg, "Either caching or replication option should be set."
277 " Both options are not supported together");
278 return 1;
281 //printf("Debug:Config=%s\n",cVal.dsn);
282 if (cVal.isCache) {
283 if (0 == strcmp(cVal.dsn,""))
285 printError(ErrBadArg, "DSN is set to NULL");
286 return 1;
290 if (cVal.isReplication || cVal.isCache) {
291 if (0 == strcmp(cVal.replConfigFile,""))
293 //TODO::check whether file exists
294 printError(ErrBadArg, "NETWORK_CONFIG_FILE is set to NULL");
295 return 1;
297 if (0 == strcmp(cVal.tableConfigFile,""))
299 //TODO::check whether file exists
300 printError(ErrBadArg, "TABLE_CONFIG_FILE is set to NULL");
301 return 1;
303 /*FILE *fp = fopen(cVal.replConfigFile,"r");
304 if( fp == NULL ) {
305 printError(ErrSysInit, "Invalid path/filename for NETWORK_CONFIG_FILE.\n");
306 return 1;
308 int count =0;
309 int nwid, port;
310 char hostname[IDENTIFIER_LENGTH];
311 char nwmode;
313 while(!feof(fp)) {
314 fscanf(fp, "%d:%d:%s\n", &nwid, &port, hostname);
315 count++;
317 if (count >2) {
318 printError(ErrSysInit, "NETWORK_CONFIG_FILE has more than 2 entries\n");
319 return 1;
323 /*if (cVal.isCache)
326 if (cVal.cacheNetworkID == -1)
328 printError(ErrBadArg, "CACHE_NETWORK_ID should not be -1");
329 return 1;
330 }else {
331 FILE *fp;
332 int nwid;
333 char hostname[IDENTIFIER_LENGTH];
334 char nwmode;
335 int port;
336 fp = fopen(Conf::config.getReplConfigFile(),"r");
337 if( fp == NULL ) {
338 printError(ErrSysInit, "Invalid path/filename for NETWORK_CONFIG_FILE.\n");
339 return 1;
341 bool found = false;
342 while(!feof(fp)) {
343 fscanf(fp, "%d:%d:%s\n", &nwid, &port, hostname);
344 if (cVal.cacheNetworkID == nwid) found = true;
346 if (!found) return 1;
349 if (cVal.nwResponseTimeout <0 || cVal.nwResponseTimeout > 60)
351 printError(ErrBadArg, "NETWORK_RESPONSE_TIMEOUT should be 0 to 60");
352 return 1;
354 if (cVal.nwConnectTimeout <0 || cVal.nwConnectTimeout > 60)
356 printError(ErrBadArg, "NETWORK_CONNECT_TIMEOUT should be 0 to 60");
357 return 1;
359 if (cVal.cacheWaitSecs <1)
361 printError(ErrBadArg, "CACHE_RECEIVER_WAIT_SECS should be >1");
362 return 1;
364 if (cVal.port <= 1024)
366 printError(ErrBadArg, "Invalid Port Number");
367 return 1;
369 if (cVal.durableMode < 1 || cVal.durableMode >4)
371 if (!cVal.isDurable) {
372 printError(ErrBadArg, "Durability is not enabled but mode is set");
373 } else {
374 printError(ErrBadArg, "Durable Mode should be 1 to 4");
376 return 1;
378 return 0;
381 int Config::readAllValues(char *fileName)
383 if (isLoaded) return 0;
384 FILE *fp;
385 if (fileName == NULL) fileName = DEFAULT_CONFIG_FILE;
386 fp = fopen(fileName,"r");
387 if( fp == NULL ) {
388 printError(ErrSysInit, "Invalid path/filename in CSQL_CONFIG_FILE.");
389 return 1;
392 int hasData = 1;
393 char buffer[1024];
394 char key[1024];
395 char value[1024];
396 while (hasData)
398 memset(buffer, 0, 1024);
399 //int ret = fscanf(fp,"%s\r",buffer);
400 int ret = readLine(fp, buffer);
401 if (ret == EOF) break;
402 bool isComment= false;
403 int posEqual =0;
404 for (int i = 0; i <1024; i++)
406 if (buffer[i] == '=' ) posEqual=i;
407 else if (buffer[i] == '#' ) { isComment = true; break; }
408 else if (buffer[i] == '\n') { break; }
409 else if (buffer[i] == '\0') { break; }
411 if (isComment) continue;
412 if (!posEqual) continue;
413 strncpy(key, buffer, posEqual);
414 key[posEqual] = '\0';
415 posEqual++;
416 strcpy(value, &buffer[posEqual]);
417 storeKeyVal(key, value);
419 fclose(fp);
420 if (validateValues())
422 return 1;
424 cVal.noOfProcessors = os::getNoOfProcessors();
425 isLoaded = true;
426 logConfig();
427 return 0;
429 void Config::logConfig()
432 logFinest(Conf::logger, "Config: MAX_SYS_DB_SIZE %d", getMaxSysDbSize());
433 logFinest(Conf::logger, "Config: MAX_DB_SIZE %d", getMaxDbSize());
434 logFinest(Conf::logger, "Config: SYS_DB_KEY %d", getSysDbKey());
435 logFinest(Conf::logger, "Config: USER_DB_KEY %d", getUserDbKey());
436 logFinest(Conf::logger, "Config: MAP_ADDRESS %ld", getMapAddress());
437 logFinest(Conf::logger, "Config: DATABASE_FILE %s", getDbFile());
438 //TODO:: for cache/sql/nw section
441 logFinest(Conf::logger, "Config: LOG_FILE %s", getLogFile());
442 logFinest(Conf::logger, "Config: LOG_LEVEL %d", getLogLevel());
443 logFinest(Conf::logger, "Config: DURABILITY %d", useDurability());
444 logFinest(Conf::logger, "Config: MMAP %d", useMmap());
445 logFinest(Conf::logger, "Config: DURABLE_MODE %d", getDurableMode());
446 logFinest(Conf::logger, "Config: MUTEX_TIMEOUT_SECS %d", getMutexSecs());
447 logFinest(Conf::logger, "Config: MUTEX_TIMEOUT_USECS %d", getMutexUSecs());
448 logFinest(Conf::logger, "Config: MUTEX_TIMEOUT_RETRIES %d", getMutexRetries());
449 logFinest(Conf::logger, "Config: LOCK_TIMEOUT_SECS %d", getLockSecs());
450 logFinest(Conf::logger, "Config: LOCK_TIMEOUT_USECS %d", getLockUSecs());
451 logFinest(Conf::logger, "Config: LOCK_TIMEOUT_RETRIES %d", getLockRetries());
453 void Config::print()
455 printf("ConfigValues\n");
456 printf(" getPageSize %d\n", getPageSize());
457 printf(" getMaxProcs %d\n", getMaxProcs());
458 printf(" getMaxSysDbSize %ld\n", getMaxSysDbSize());
459 printf(" getMaxDbSize %ld\n", getMaxDbSize());
460 printf(" getSysDbKey %d\n", getSysDbKey());
461 printf(" getUserDbKey %d\n", getUserDbKey());
462 printf(" getLogFile %s\n", getLogFile());
463 printf(" getLogLevel %d\n", getLogLevel());
464 printf(" getDatabaseFile %s\n", getDbFile());
465 printf(" getMapAddress %ld\n", getMapAddress());
466 printf(" getMutexSecs %d\n", getMutexSecs());
467 printf(" getMutexUSecs %d\n", getMutexUSecs());
468 printf(" getMutexRetries %d\n", getMutexRetries());
469 printf(" getLockSecs %d\n", getLockSecs());
470 printf(" getLockUSecs %d\n", getLockUSecs());
471 printf(" getLockRetries %d\n", getLockRetries());
472 printf(" useCache %d\n", useCache());
473 printf(" getDSN %s\n", getDSN());
474 printf(" getDsConfigFile %s\n",getDsConfigFile());
475 printf(" getTableConfigFile %s\n", getTableConfigFile());
476 printf(" isTwoWayCache %d\n", useTwoWayCache());
477 printf(" getCacheMode %d\n", getCacheMode());
478 printf(" getCacheWaitSecs %d\n", getCacheWaitSecs());
479 printf(" useCsqlSqlServer %d\n", useCsqlSqlServer());
480 printf(" getPort %d\n", getPort());
481 printf(" useReplication %d\n", useReplication());
482 printf(" isDurable %d\n", useDurability());
483 printf(" getReplConfigFile %s\n", getReplConfigFile());
484 printf(" getSiteID %d\n", getSiteID());
485 printf(" getMsgKey %d\n", getMsgKey());
486 printf(" getShmIDKey %d\n", getShmIDKey());
489 DbRetVal SiteInfo::populateSiteInfoList()
491 if (!Conf::config.useReplication()) return OK;
492 FILE *fp = fopen( Conf::config.getReplConfigFile(), "r");
493 if (fp == NULL) {
494 printError(ErrSysInit, "Invalid path/filename for REPL_CONFIG_FILE.\n");
495 return ErrSysInit;
497 char line[128];
498 while(fgets(line, sizeof (line), fp) != NULL) {
499 SiteInfoData *sInfo = new SiteInfoData();
500 char *token = strtok(line, ":");
501 sInfo->siteId = atoi(token);
502 if ((token = strtok(NULL, ":")) != NULL)
503 strncpy(sInfo->hostName, token, IDENTIFIER_LENGTH);
504 if ((token = strtok(NULL, ":")) != NULL) sInfo->port = atoi(token);
505 if ((token = strtok(NULL, ":")) != NULL)
506 strncpy(sInfo->mode, token, 32);
507 siteInfoList.append(sInfo);
508 if(strncasecmp(sInfo->mode, "ASYNC", 5)==0) asyncSiteList.append(sInfo);
509 if(strncasecmp(sInfo->mode, "SYNC", 4)==0) syncSiteList.append(sInfo);
511 fclose(fp);
512 return OK;
515 bool SiteInfo::isAsyncSitePresent()
517 bool async = false;
518 if (!Conf::config.useReplication()) return false;
519 ListIterator it = siteInfoList.getIterator();
520 while (it.hasElement()) {
521 SiteInfoData *data = (SiteInfoData *) it.nextElement();
522 if (strncmp(data->mode, "ASYNC", 5) == 0) { async = true; break; }
524 return async;
527 bool SiteInfo::isSyncSitePresent()
529 bool sync = false;
530 if (!Conf::config.useReplication()) return false;
531 ListIterator it = siteInfoList.getIterator();
532 while (it.hasElement()) {
533 SiteInfoData *data = (SiteInfoData *) it.nextElement();
534 if (strncmp(data->mode, "SYNC", 4) == 0) { sync = true; break; }
536 return sync;
539 SiteInfo::~SiteInfo()
541 // ListIterator it = siteInfoList.getIterator();
542 // while(it.hasElement()) delete (SiteInfoData *) it.nextElement();
543 // siteInfoList.reset();
544 ListIterator it = asyncSiteList.getIterator();
545 while(it.hasElement()) delete (SiteInfoData *) it.nextElement();
546 asyncSiteList.reset();
547 it = syncSiteList.getIterator();
548 while(it.hasElement()) delete (SiteInfoData *) it.nextElement();
549 syncSiteList.reset();