浏览代码

Support for database URIs

Jan Janak 18 年之前
父节点
当前提交
c949f162f3
共有 4 个文件被更改,包括 255 次插入56 次删除
  1. 39 44
      db/db_pool.c
  2. 27 12
      db/db_pool.h
  3. 123 0
      db/db_uri.c
  4. 66 0
      db/db_uri.h

+ 39 - 44
db/db_pool.c

@@ -2,6 +2,7 @@
  * $Id$
  *
  * Copyright (C) 2001-2005 iptel.org
+ * Copyright (C) 2006-2007 iptelorg GmbH
  *
  * This file is part of ser, a free SIP server.
  *
@@ -25,37 +26,50 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <unistd.h>
+#include <string.h>
 #include "../dprint.h"
 #include "db_pool.h"
 
+SLIST_HEAD(db_pool_head, db_pool_entry);
 
-/* The head of the pool */
-static struct pool_con* db_pool = 0;
+/* The global connection pool */
+struct db_pool_head db_pool = SLIST_HEAD_INITIALIZER(db_pool);
+
+
+int db_pool_entry_init(struct db_pool_entry *entry, void* free_func, db_uri_t* uri)
+{
+	if (db_drv_init(&entry->drv_gen, free_func) < 0) return -1;
+	SLIST_NEXT(entry, next) = NULL;
+	entry->uri = uri;
+	entry->ref = 1;
+	return 0;
+}
+
+
+void db_pool_entry_free(struct db_pool_entry* entry)
+{
+	db_drv_free(&entry->drv_gen);
+	entry->uri = NULL;
+	entry->ref = 0;
+}
 
 
 /*
  * Search the pool for a connection with
- * the identifier equal to id, NULL is returned
+ * the URI equal to uri, NULL is returned
  * when no connection is found
  */
-struct pool_con* pool_get(struct db_id* id)
+struct db_pool_entry* db_pool_get(db_uri_t* uri)
 {
-	struct pool_con* ptr;
+	db_pool_entry_t* ptr;
 
-	if (!id) {
-		LOG(L_ERR, "pool_get: Invalid parameter value\n");
-		return 0;
-	}
-
-	ptr = db_pool;
-	while (ptr) {
-		if (cmp_db_id(id, ptr->id)) {
+	SLIST_FOREACH(ptr, &db_pool, next) {
+		if (db_uri_cmp(ptr->uri, uri)) {
 			ptr->ref++;
 			return ptr;
 		}
-		ptr = ptr->next;
 	}
-
 	return 0;
 }
 
@@ -63,12 +77,9 @@ struct pool_con* pool_get(struct db_id* id)
 /*
  * Insert a new connection into the pool
  */
-void pool_insert(struct pool_con* con)
+void db_pool_put(db_pool_entry_t* entry)
 {
-	if (!con) return;
-
-	con->next = db_pool;
-	db_pool = con;
+	SLIST_INSERT_HEAD(&db_pool, entry, next);
 }
 
 
@@ -82,39 +93,23 @@ void pool_insert(struct pool_con* con)
  * The function returns -1 if the connection is
  * not in the pool.
  */
-int pool_remove(struct pool_con* con)
+int db_pool_remove(db_pool_entry_t* entry)
 {
-	struct pool_con* ptr;
+	db_pool_entry_t* ptr, *tmp_ptr;
 
-	if (!con) return -2;
+	if (!entry) return -2;
 
-	if (con->ref > 1) {
+	if (entry->ref > 1) {
 		     /* There are still other users, just
 		      * decrease the reference count and return
 		      */
-		DBG("pool_remove: Connection still kept in the pool\n");
-		con->ref--;
+		DBG("db_pool_remove: Connection still kept in the pool\n");
+		entry->ref--;
 		return 0;
 	}
 
-	DBG("pool_remove: Removing connection from the pool\n");
-
-	if (db_pool == con) {
-		db_pool = db_pool->next;
-	} else {
-		ptr = db_pool;
-		while(ptr) {
-			if (ptr->next == con) break;
-			ptr = ptr->next;
-		}
-		if (!ptr) {
-			LOG(L_ERR, "pool_remove: Weird, connection not found in the pool\n");
-			return -1;
-		} else {
-			     /* Remove the connection from the pool */
-			ptr->next = con->next;
-		}
-	}
+	DBG("db_pool_remove: Removing connection from the pool\n");
 
+	SLIST_REMOVE(&db_pool, entry, db_pool_entry, next);
 	return 1;
 }

+ 27 - 12
db/db_pool.h

@@ -2,6 +2,7 @@
  * $Id$
  *
  * Copyright (C) 2001-2005 iptel.org
+ * Copyright (C) 2006-2007 iptelorg GmbH
  *
  * This file is part of ser, a free SIP server.
  *
@@ -26,10 +27,16 @@
  */
 
 #ifndef _DB_POOL_H
-#define _DB_POOL_H
+#define _DB_POOL_H  1
 
-#include "db_id.h"
-#include "db_con.h"
+#include <sys/types.h>
+#include "db_drv.h"
+#include "../list.h"
+#include "db_uri.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
 
 
 /*
@@ -40,11 +47,16 @@
  * created by the backends) must have these
  * attributes.
  */
-struct pool_con {
-	struct db_id* id;        /* Connection identifier */
-	unsigned int ref;        /* Reference count */
-	struct pool_con* next;   /* Next element in the pool */
-};
+typedef struct db_pool_entry {
+	db_drv_t drv_gen;  /* Generic part of the driver specific data */
+	SLIST_ENTRY(db_pool_entry) next;
+	db_uri_t* uri;     /* Pointer to the URI representing the connection */
+	unsigned int ref;  /* Reference count */
+} db_pool_entry_t;
+
+
+int db_pool_entry_init(struct db_pool_entry *entry, void* free_func, db_uri_t* uri);
+void db_pool_entry_free(struct db_pool_entry* entry);	
 
 
 /*
@@ -52,13 +64,13 @@ struct pool_con {
  * the identifier equal to id, NULL is returned
  * when no connection is found
  */
-struct pool_con* pool_get(struct db_id* id);
+struct db_pool_entry* db_pool_get(db_uri_t* uri);
 
 
 /*
  * Insert a new connection into the pool
  */
-void pool_insert(struct pool_con* con);
+void db_pool_put(struct db_pool_entry* entry);
 
 
 /*
@@ -71,7 +83,10 @@ void pool_insert(struct pool_con* con);
  * The function returns -1 if the connection is
  * not in the pool.
  */
-int pool_remove(struct pool_con* con);
+int db_pool_remove(struct db_pool_entry* entry);
 
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
 
-#endif /* _POOL_H */
+#endif /* _DB_POOL_H */

+ 123 - 0
db/db_uri.c

@@ -0,0 +1,123 @@
+/* 
+ * $Id$
+ *
+ * Copyright (C) 2001-2005 FhG FOKUS
+ * Copyright (C) 2006-2007 iptelorg GmbH
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <string.h>
+#include "../dprint.h"
+#include "../mem/mem.h"
+#include "../ut.h"
+#include "db_uri.h"
+
+
+/* compare s1 & s2  with a function f (which should return 0 if ==);
+ * s1 & s2 can be null
+ * return 0 if match, 1 if not */
+#define CMP_STR(s1, s2, f) \
+	((s1) != (s2)) && ((s1) == 0 || (s2) == 0 || (f)((s1), (s2)) != 0)
+
+
+unsigned char db_uri_cmp(db_uri_t* uri1, db_uri_t* uri2)
+{
+	if (!uri1 || !uri2) return 0;
+
+	if (CMP_STR(uri1->scheme.s, uri2->scheme.s, strcmp)) return 0;
+
+	if (uri1->cmp) {
+		return uri1->cmp(uri1, uri2);
+	} else {
+		/* No driver specific comparison function, compare bodies
+		 * byte-wise
+		 */
+		if (CMP_STR(uri1->body.s, uri2->body.s, strcmp)) return 0;
+	}
+	return 1;
+}
+
+
+
+/*
+ * Create a new database URI
+ */
+db_uri_t* db_uri(const char* uri)
+{
+    char* colon;
+    int len;
+    db_uri_t* r;
+    
+    r = (db_uri_t*)pkg_malloc(sizeof(db_uri_t));
+    if (r == NULL) goto error;
+    memset(r, '\0', sizeof(db_uri_t));
+	if (db_gen_init(&r->gen) < 0) goto error;	
+
+    len = strlen(uri);
+    colon = q_memchr((char*)uri, ':', len);
+    if (colon == NULL) {
+		r->scheme.s = pkg_malloc(len + 1);
+		if (r->scheme.s == NULL) goto error;
+		memcpy(r->scheme.s, uri, len);
+		r->scheme.len = len;
+    } else {
+		r->scheme.len = colon - uri;
+		r->scheme.s = pkg_malloc(r->scheme.len + 1);
+		if (r->scheme.s == NULL) goto error;
+		memcpy(r->scheme.s, uri, colon - uri);
+		
+		r->body.len = len - r->scheme.len - 1;
+		r->body.s = pkg_malloc(r->body.len + 1);
+		if (r->body.s == NULL) goto error;
+		memcpy(r->body.s, colon + 1, r->body.len);
+		r->body.s[r->body.len] = '\0';
+    }
+    r->scheme.s[r->scheme.len] = '\0';
+
+	/* Call db_uri function if the driver has it */
+	if (db_drv_call(&r->scheme, "db_uri", r, 0) < 0) goto error;
+    return r;
+    
+ error:
+    ERR("db_uri: Error while creating db_uri structure\n");
+	if (r) {
+		db_gen_free(&r->gen);
+		if (r->body.s) pkg_free(r->body.s);
+		if (r->scheme.s) pkg_free(r->scheme.s);
+		pkg_free(r);
+	}
+    return 0;
+}
+
+
+/*
+ * Free a connection identifier
+ */
+void db_uri_free(db_uri_t* uri)
+{
+    if (uri == NULL) return;
+	db_gen_free(&uri->gen);
+    if (uri->body.s) pkg_free(uri->body.s);
+    if (uri->scheme.s) pkg_free(uri->scheme.s);
+    pkg_free(uri);
+}

+ 66 - 0
db/db_uri.h

@@ -0,0 +1,66 @@
+/* 
+ * $Id$
+ *
+ * Copyright (C) 2001-2005 FhG FOKUS
+ * Copyright (C) 2006-2007 iptelorg GmbH
+ *
+ * This file is part of ser, a free SIP server.
+ *
+ * ser is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * For a license to use the ser software under conditions
+ * other than those described here, or to purchase support for this
+ * software, please contact iptel.org by e-mail at the following addresses:
+ *    [email protected]
+ *
+ * ser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _DB_URI_H
+#define _DB_URI_H  1
+
+#include "../str.h"
+#include "db_gen.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct db_uri;
+
+typedef unsigned char (db_uri_cmp_t)(struct db_uri* uri1, struct db_uri* uri2);
+
+typedef struct db_uri {
+	db_gen_t gen;      /* Generic part of the structure */
+    str scheme;        /* URI scheme */
+    str body;          /* Entire URI body */
+    db_uri_cmp_t* cmp; /* Comparison function */
+} db_uri_t;
+
+
+/*
+ * Create a database URI structure
+ */
+struct db_uri* db_uri(const char* uri);
+
+void db_uri_free(struct db_uri* uri);
+
+unsigned char db_uri_cmp(struct db_uri* uri1, struct db_uri* uri2);
+
+db_uri_cmp_t db_uri_cmp;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _DB_URI_H */