Changeset 5300

Change to use a registry for the cache

Committed by:  mjagdis
Date:  Jan 07 2009 * 18:26 (about 1 year ago)

Affected files:

callweaver/trunk/res/res_sqlite.c (unified diff)

r5262r5300
2121 #include <pthread.h>
2222 #include <sqlite3.h>
2323
24 #include "callweaver/hashtable_helper.h"
24 #include "callweaver/registry.h"
2525 #include "callweaver/switch.h"
2626 #include "callweaver/cdr.h"
2727 #include "callweaver/file.h"
------
108108 static char switch_table[ARRAY_SIZE];
109109 static char switch_dbfile[ARRAY_SIZE];
110110
111 typedef struct extension_cache extension_cache;
112111 typedef struct switch_config switch_config;
113112
114113 static int exist_callback(void *pArg, int argc, char **argv, char **columnNames);
115114
116 struct extension_cache {
117 time_t expires;
118 char exten[ARRAY_SIZE];
119 char context[ARRAY_SIZE];
120 char app_name[ARRAY_SIZE][ARRAY_LEN];
121 char app_data[ARRAY_SIZE][ARRAY_LEN];
122 int argc;
123 };
124
125115 struct switch_config {
126116 int timeout;
127117 int fd;
------
133123 static char clidb[ARRAY_SIZE] = {"/usr/local/callweaver/sqlite/callweaver.db"};
134124
135125
136 static hash_table_t extens;
137
138
139126 static const char tdesc[] = "SQLite SQL Interface";
140127
141128 static void *app;
------
145132 static const char syntax[] = "SQL(\"[sql statement]\"[, dbname])";
146133
147134
135 struct extcon {
136 const char *exten;
137 const char *context;
138 };
139
140 struct cache {
141 struct cw_object obj;
142 time_t expires;
143 char exten[ARRAY_SIZE];
144 char context[ARRAY_SIZE];
145 char app_name[ARRAY_SIZE][ARRAY_LEN];
146 char app_data[ARRAY_SIZE][ARRAY_LEN];
147 int argc;
148 };
149
150
151 static const char *cache_object_name(struct cw_object *obj)
152 {
153 const struct cache *it = container_of(obj, struct cache, obj);
154 return it->exten;
155 }
156
157 static int cache_object_match(struct cw_object *obj, const void *pattern)
158 {
159 const struct cache *it = container_of(obj, struct cache, obj);
160 const struct extcon *extcon = pattern;
161 return !strcmp(it->exten, extcon->exten) && !strcmp(it->context, extcon->context);
162 }
163
164 const struct cw_object_isa cw_object_isa_cache = {
165 .name = cache_object_name,
166 };
167
168 static struct cw_registry cache_registry = {
169 .name = "SQLite cache",
170 .match = cache_object_match,
171 };
172
173
148174 static void pick_path(char *dbname,char *buf, size_t size) {
149175
150176 memset(buf,0,size);
------
263289 }
264290
265291 static int sqlite_cli(int fd, int argc, char *argv[]) {
292 char sqlbuf[1024];
293 char path[ARRAY_SIZE];
294 switch_config config;
295 char *sql = NULL;
266296 char *errmsg = NULL;
267 char sqlbuf[1024];
268297 int x = 0;
269298 int start = 0;
270 switch_config config;
271 extension_cache *cache;
299
272300 memset(&config,0,sizeof(switch_config));
273301 sqlite3 *db=NULL;
274 hash_entry_t *entry;
275 char path[ARRAY_SIZE];
276 char *sql = NULL;
277302
278303 if (has_switch) {
279304 if (argv[1] && !strcmp(argv[1],"switchtable")) {
------
385410 return 0;
386411 }
387412 else if (argv[1] && !strcmp(argv[1],"clearcache")) {
388 hash_search_t search;
389
390 cw_mutex_lock(&switch_lock);
391
392 for (entry = hash_first_entry(&extens, &search);
393 entry;
394 entry = hash_next_entry(&search))
395 {
396 cache = hash_get_key(&extens, entry);
397 cw_cli(fd,"OK Erasing %s@%s\n",cache->exten,cache->context);
398 free(cache);
399 cache = NULL;
400 hash_delete_entry(entry);
401 }
402 hash_delete_table(&extens);
403 hash_init_table(&extens, HASH_STRING_KEYS);
404 /*
405 elem = extens.first;
406 while ( elem ){
407 HashElem *next_elem = elem->next;
408 cache = elem->data;
409 cw_cli(fd,"OK Erasing %s@%s\n",cache->exten,cache->context);
410 free(cache);
411 cache = NULL;
412 elem = next_elem;
413 }
414 sqlite3HashClear(&extens);
415 sqlite3HashInit(&extens,SQLITE_HASH_STRING,COPY_KEYS);
416 */
417 cw_mutex_unlock(&switch_lock);
413 cw_registry_flush(&cache_registry);
418414 cw_cli(fd,"\nOK. Cache Clear!\n\n");
419415 return 0;
420416 }
------
461457
462458
463459 static int exist_callback(void *pArg, int argc, char **argv, char **columnNames){
464 extension_cache *cache = NULL;
465 char key[ARRAY_SIZE];
460 struct extcon extcon;
461 struct cw_object *obj;
462 struct cache *cache;
466463 int pri;
467464 time_t now;
468465 int needs_add=0;
469466 switch_config *config=NULL;
470467 int timeout=0;
471468 char *context;
469 const char *p;
470 unsigned int hash;
472471
473
474472 if (pArg) {
475473 config = pArg;
476474 timeout = config->timeout;
------
485483 return 0;
486484 }
487485
488 snprintf(key, ARRAY_SIZE, "%s.%s", argv[1], context);
486 extcon.exten = argv[1];
487 extcon.context = context;
488 hash = 0;
489 for (p = argv[1]; *p; hash = cw_hash_add(hash, *(p++)));
490 for (p = context; *p; hash = cw_hash_add(hash, *(p++)));
491
489492 time(&now);
490493 pri = atoi(argv[2]);
491494
492495 //cache = (extension_cache *) sqlite3HashFind(&extens,key,strlen(key));
493 cw_core_hash_get ( &extens, key, (void*)cache );
494
495 if (! cache) {
496 cache = malloc(sizeof(extension_cache));
496 if ((obj = cw_registry_find(&cache_registry, 1, hash, &extcon))) {
497 cache = container_of(obj, struct cache, obj);
498 } else {
499 cache = malloc(sizeof(*cache));
500 cw_object_init(cache, &cw_object_isa_cache, NULL, 0);
497501 needs_add = 1;
498502 }
499503
500 if (needs_add || cache->expires < now) {
501 memset(cache,0,sizeof(extension_cache));
502 strncpy(cache->context,argv[0],sizeof(cache->context));
503 strncpy(cache->exten,argv[1],sizeof(cache->exten));
504 }
505 cache->expires = now + timeout;
504 if (cache) {
505 if (needs_add || cache->expires < now) {
506 memset(cache, 0, sizeof(*cache));
507 strncpy(cache->context, argv[0], sizeof(cache->context));
508 strncpy(cache->exten, argv[1], sizeof(cache->exten));
509 }
510 cache->expires = now + timeout;
506511
507 if (config && ! config->seeheads) {
508 cw_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch: extension %s@%s will expire in %d seconds\n",argv[1],context,timeout);
509 config->seeheads = 1;
510 }
512 if (config && ! config->seeheads) {
513 cw_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch: extension %s@%s will expire in %d seconds\n",argv[1],context,timeout);
514 config->seeheads = 1;
515 }
511516
512 strncpy(cache->app_name[pri], argv[3], sizeof(cache->app_name[pri]));
513 strncpy(cache->app_data[pri], argv[4], sizeof(cache->app_data[pri]));
517 strncpy(cache->app_name[pri], argv[3], sizeof(cache->app_name[pri]));
518 strncpy(cache->app_data[pri], argv[4], sizeof(cache->app_data[pri]));
514519
515 if (needs_add) {
516 //sqlite3HashInsert(&extens, key, strlen(key), cache);
517 cw_core_hash_insert ( &extens, key, cache );
520 if (needs_add) {
521 //sqlite3HashInsert(&extens, key, strlen(key), cache);
522 cw_registry_replace(&cache_registry, hash, &extcon, &cache->obj);
523 } else
524 cw_object_put(cache);
518525 }
526
519527 return 0;
520528 }
521529
------
524532
525533 static int SQLiteSwitch_exists(struct cw_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
526534 {
527 int res = 0;
528 char key[ARRAY_SIZE];
529 extension_cache *cache = NULL;
535 char databuf[ARRAY_SIZE];
536 switch_config config;
537 struct extcon extcon;
530538 time_t now;
539 struct cw_object *obj;
540 struct cache *cache;
531541 char *errmsg = NULL;
532 char databuf[ARRAY_SIZE];
533542 char *table,*tmp,*filename=NULL;
534543 int expires=0;
535 switch_config config;
536544 sqlite3 *db=NULL;
537545 char *sql = NULL;
546 const char *p;
547 unsigned int hash;
548 int res = 0;
538549
539550 memset(&config,0,sizeof(switch_config));
540551 memset(databuf,0,ARRAY_SIZE);
------
561572 if (!filename)
562573 filename = switch_dbfile;
563574
575 extcon.exten = exten;
576 extcon.context = context;
577 hash = 0;
578 for (p = exten; *p; hash = cw_hash_add(hash, *(p++)));
579 for (p = context; *p; hash = cw_hash_add(hash, *(p++)));
564580
565581 //cw_log(CW_LOG_NOTICE, "SQLiteSwitch_exists %d: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", res, context, exten, priority, callerid ? callerid : "<unknown>", data);
566582 time(&now);
567 snprintf(key, ARRAY_SIZE, "%s.%s", exten, context);
568583
569 cw_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch_exists lookup [%s]: ",key);
584 cw_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch_exists lookup [%s@%s]: ", exten, context);
570585
571586 //cache = (extension_cache *) sqlite3HashFind(&extens,key,strlen(key));
572 cw_core_hash_get ( &extens, key, (void*)cache );
587 obj = cw_registry_find(&cache_registry, 1, hash, &extcon);
588 cache = container_of(obj, struct cache, obj);
573589
574 cw_verbose("%s\n",cache ? "match" : "fail");
590 cw_verbose("%s\n", (obj ? "match" : "fail"));
575591
576
577
578 if (! cache || (cache && cache->expires < now) ) {
592 if (!obj || (obj && cache->expires < now)) {
593 if (obj)
594 cw_object_put(cache);
595 cache = NULL;
579596 if ((db = open_db(filename))) {
580
581
582 if((sql = sqlite3_mprintf("select *,'%q' as real_context from %q where (context='%q' or context='_any_') and exten='%q' order by context,exten,pri",
583 context,
584 table,
585 context,
586 exten
587 ))) {
588 sqlite3_exec(
589 db,
590 sql,
591 exist_callback,
592 &config,
593 &errmsg
594 );
597 sql = sqlite3_mprintf("select *,'%q' as real_context from %q where (context='%q' or context='_any_') and exten='%q' order by context,exten,pri",
598 context, table, context, exten);
599 if (sql) {
600 sqlite3_exec(db, sql, exist_callback, &config, &errmsg);
595601 if (errmsg) {
596602 cw_log(CW_LOG_WARNING,"SQL ERR [%s]\n",errmsg);
597603 sqlite3_free(errmsg);
------
606612 sql = NULL;
607613 }
608614 //cache = (extension_cache *) sqlite3HashFind(&extens,key,strlen(key));
609 cw_core_hash_get ( &extens, key, (void*)cache );
615 if ((obj = cw_registry_find(&cache_registry, 1, hash, &extcon)))
616 cache = container_of(obj, struct cache, obj);
610617 } else {
611618 cw_log(CW_LOG_WARNING,"ERROR OPEINING DB.\n");
612619 return -1;
613620 }
621 }
614622
615 }
616
617623 if (cache) {
618 cw_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch_exists lookup [%s,%d]: ",key,priority);
624 cw_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch_exists lookup [%s@%s,%d]: ", exten, context, priority);
619625 res = strlen(cache->app_name[priority]) ? 1 : 0;
626 cw_object_put(cache);
620627 cw_verbose("%s\n",res ? "match" : "fail");
621628 }
622629
------
638645
639646 static int SQLiteSwitch_exec(struct cw_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
640647 {
648 char app_data[1024];
649 struct extcon extcon;
650 time_t now;
651 struct cw_object *obj;
652 struct cache *cache;
653 const char *p;
654 unsigned int hash;
641655 int res = 0;
642 extension_cache *cache = NULL;
643 char key[ARRAY_SIZE];
644 time_t now;
645 char app_data[1024];
646
647656
648657 time(&now);
649658 //cw_log(CW_LOG_NOTICE, "SQLiteSwitch_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
650659
651 snprintf(key, ARRAY_SIZE, "%s.%s", exten, context);
660 extcon.exten = exten;
661 extcon.context = context;
662 hash = 0;
663 for (p = exten; *p; hash = cw_hash_add(hash, *(p++)));
664 for (p = context; *p; hash = cw_hash_add(hash, *(p++)));
652665
653 cw_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch_exec lookup [%s]: ",key);
666 cw_verbose(VERBOSE_PREFIX_2 "SQLiteSwitch_exec lookup [%s@%s]: ", exten, context);
667
654668 //cache = (extension_cache *) sqlite3HashFind(&extens,key,strlen(key));
655 cw_core_hash_get ( &extens, key, (void*)cache );
656 cw_verbose("%s\n",cache ? "match" : "fail");
669 obj = cw_registry_find(&cache_registry, 1, hash, &extcon);
657670
658 if (cache) {
671 cw_verbose("%s\n", (obj ? "match" : "fail"));
672
673 if (obj) {
674 cache = container_of(obj, struct cache, obj);
659675 pbx_substitute_variables_helper(chan, cache->app_data[priority], app_data, sizeof(app_data));
660676 res = cw_function_exec_str(chan,
661677 cw_hash_string(cache->app_name[priority]),
662678 cache->app_name[priority], app_data, NULL, 0);
679 cw_object_put(cache);
663680 }
664
681
665682 return res;
666683 }
667684
------
11721189 static void release(void)
11731190 {
11741191 if (has_switch)
1175 hash_delete_table(&extens);
1192 cw_registry_destroy(&cache_registry);
11761193 // sqlite3HashClear(&extens);
11771194 }
11781195
------
11921209
11931210 if (has_switch) {
11941211 //sqlite3HashInit(&extens,SQLITE_HASH_STRING,COPY_KEYS);
1195 hash_init_table(&extens, HASH_STRING_KEYS);
1212 cw_registry_init(&cache_registry, 1024);
11961213 }
11971214
11981215 if (has_cli) {