Răsfoiți Sursa

- new db api, revision 2.0

Jan Janak 18 ani în urmă
părinte
comite
0f7f49b2d7
22 a modificat fișierele cu 299 adăugiri și 78 ștergeri
  1. 5 0
      db/db.c
  2. 18 0
      db/db.h
  3. 77 20
      db/db_cmd.c
  4. 25 5
      db/db_cmd.h
  5. 4 0
      db/db_con.c
  6. 6 0
      db/db_con.h
  7. 27 31
      db/db_ctx.c
  8. 6 1
      db/db_ctx.h
  9. 4 0
      db/db_drv.c
  10. 7 1
      db/db_drv.h
  11. 16 8
      db/db_fld.c
  12. 12 3
      db/db_fld.h
  13. 5 1
      db/db_gen.c
  14. 7 5
      db/db_gen.h
  15. 4 0
      db/db_pool.c
  16. 6 0
      db/db_pool.h
  17. 9 2
      db/db_rec.c
  18. 9 1
      db/db_rec.h
  19. 32 0
      db/db_res.c
  20. 12 0
      db/db_res.h
  21. 4 0
      db/db_uri.c
  22. 4 0
      db/db_uri.h

+ 5 - 0
db/db.c

@@ -31,6 +31,9 @@
   *  2004-06-06  bind_dbmod takes dbf as parameter (andrei)
   */
 
+/** \ingroup DB_API
+ * @{
+ */
 
 #include "../dprint.h"
 #include "../sr_module.h"
@@ -42,3 +45,5 @@
 #include "db.h"
 
 struct db_root db = DBLIST_INITIALIZER(db);
+
+/** @} */

+ 18 - 0
db/db.h

@@ -25,9 +25,19 @@
  * 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_H
 #define _DB_H  1
 
+/**
+ * \defgroup DB_API Database Abstraction Layer
+ * \brief brief description
+ *
+ * I wonder where this text goes.
+ * @{
+ */
+
+
 #include "db_gen.h"
 #include "db_ctx.h"
 #include "db_uri.h"
@@ -42,12 +52,20 @@ extern "C" {
 
 struct db_gen;
 
+
 DBLIST_HEAD(db_root);
 
+/** \brief The root of all DB API structures
+ *
+ *  This is the root linked list of all database
+ *  structures allocated in SER
+ */
 extern struct db_root db;
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_H */

+ 77 - 20
db/db_cmd.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <string.h>
 #include "../dprint.h"
 #include "../mem/mem.h"
@@ -33,12 +35,14 @@
 #include "db_cmd.h"
 
 
-db_cmd_t* db_cmd(enum db_cmd_type type, db_ctx_t* ctx, char* table, db_fld_t* match, db_fld_t* fld)
+db_cmd_t* db_cmd(enum db_cmd_type type, db_ctx_t* ctx, char* table, 
+				 db_fld_t* result, db_fld_t* params)
 {
 	char* fname;
     db_cmd_t* res;
 	db_con_t* con;
-	int i, r;
+	db_fld_t* f;
+	int i, r, j;
 
     res = (db_cmd_t*)pkg_malloc(sizeof(db_cmd_t));
     if (res == NULL) goto err;
@@ -50,12 +54,28 @@ db_cmd_t* db_cmd(enum db_cmd_type type, db_ctx_t* ctx, char* table, db_fld_t* ma
     res->table.s = (char*)pkg_malloc(res->table.len);
     if (res->table.s == NULL) goto err;
     memcpy(res->table.s, table, res->table.len);
+
 	res->type = type;
-	res->match = match;
-	res->fld = fld;
+	res->result = result;
+	res->params = params;
+
+	for(i = 0; i < ctx->con_n; i++) {
+		con = ctx->con[i];
+
+		if (!DB_FLD_EMPTY(result)) {
+			for(j = 0; !DB_FLD_LAST(result[j]); j++) {
+				if (db_fld_init(result + j, 1) < 0) goto err;
+				if (db_drv_call(&con->uri->scheme, "db_fld", result + j, i) < 0) goto err;
+			}
+		}
+
+		if (!DB_FLD_EMPTY(params)) {
+			for(j = 0; !DB_FLD_LAST(params[j]); j++) {
+				if (db_fld_init(params + j, 1) < 0) goto err;
+				if (db_drv_call(&con->uri->scheme, "db_fld", params + j, i) < 0) goto err;
+			}
+		}
 
-	i = 0;
-	DBLIST_FOREACH(con, &ctx->con) {
 		r = db_drv_call(&con->uri->scheme, "db_cmd", res, i);
 		if (r < 0) goto err;
 		if (r > 0) {
@@ -74,7 +94,7 @@ db_cmd_t* db_cmd(enum db_cmd_type type, db_ctx_t* ctx, char* table, db_fld_t* ma
 			default: ERR("db_cmd: Unsupported command type\n"); goto err;
 			}
 
-			r = db_drv_func(&(res->exec[i]), &con->uri->scheme, fname);
+			r = db_drv_func((void*)&(res->exec[i]), &con->uri->scheme, fname);
 			if (r < 0) goto err;
 			if (r > 0) {
 				ERR("DB driver %.*s does not provide runtime execution function %s\n",
@@ -82,23 +102,56 @@ db_cmd_t* db_cmd(enum db_cmd_type type, db_ctx_t* ctx, char* table, db_fld_t* ma
 				goto err;
 			}
 		}
-		i++;
+
+		r = db_drv_func((void*)(&res->first[i]), &con->uri->scheme, "db_first");
+		if (r < 0) goto err;
+		if (r > 0) {
+			ERR("DB driver %.*s does not implement mandatory db_first function\n",
+				con->uri->scheme.len, ZSW(con->uri->scheme.s));
+			goto err;
+		}
+
+		r = db_drv_func((void*)(&res->next[i]), &con->uri->scheme, "db_next");
+		if (r < 0) goto err;
+		if (r > 0) {
+			ERR("DB driver %.*s does not implement mandatory db_next function\n",
+				con->uri->scheme.len, ZSW(con->uri->scheme.s));
+			goto err;
+		}
+
+
 	}
     return res;
 
  err:
     ERR("db_cmd: Cannot create db_cmd structure\n");
-	db_gen_free(&res->gen);
-    if (res == NULL) return NULL;
-    if (res->table.s) pkg_free(res->table.s);
-    pkg_free(res);
-    return NULL;
+    if (res) {
+		db_gen_free(&res->gen);
+		if (res->table.s) pkg_free(res->table.s);
+		pkg_free(res);
+	}
+	return NULL;
 }
 
 
 void db_cmd_free(db_cmd_t* cmd)
 {
+	int i;
+
     if (cmd == NULL) return;
+
+	if (!DB_FLD_EMPTY(cmd->result)) {
+		for(i = 0; !DB_FLD_LAST(cmd->result[i]); i++) {
+			db_fld_close(cmd->result + i, 1);
+		}
+	}
+	
+	if (!DB_FLD_EMPTY(cmd->params)) {
+		for(i = 0; !DB_FLD_LAST(cmd->params[i]); i++) {
+			db_fld_close(cmd->params + i, 1);
+		}
+	}
+	
 	db_gen_free(&cmd->gen);
     if (cmd->table.s) pkg_free(cmd->table.s);
     pkg_free(cmd);
@@ -107,14 +160,18 @@ void db_cmd_free(db_cmd_t* cmd)
 
 int db_exec(db_res_t** res, db_cmd_t* cmd)
 {
-	db_con_t* con;
 	int i;
+	db_res_t* r = NULL;
 
-	i = 0;
-	DBLIST_FOREACH(con, &cmd->ctx->con) {
-		db_payload_idx = i;
-		if (cmd->exec[i](cmd) < 0) return -1;
-		i++;
+	if (cmd->type == DB_GET) {
+		r = db_res(cmd);
+		if (r == NULL) return -1;
+		if (res) *res = r;
 	}
-	return 0;
+
+	/* FIXME */
+	db_payload_idx = 0;
+	return cmd->exec[0](r, cmd);
 }
+
+/** @} */

+ 25 - 5
db/db_cmd.h

@@ -29,10 +29,19 @@
 #ifndef _DB_CMD_H
 #define _DB_CMD_H  1
 
+/** \ingroup DB_API 
+ * @{ 
+ */
+
+/** \file
+ * Representation of database commands
+ */
+
 #include "db_fld.h"
 #include "db_drv.h"
 #include "db_gen.h"
 #include "db_res.h"
+#include "db_rec.h"
 #include "db_ctx.h"
 
 #ifdef __cplusplus
@@ -41,6 +50,12 @@ extern "C" {
 
 struct db_cmd;
 struct db_res;
+struct db_rec;
+
+typedef int (*db_exec_func_t)(struct db_res* res, struct db_cmd* cmd);
+typedef int (*db_first_func_t)(struct db_res* res);
+typedef int (*db_next_func_t)(struct db_rec* rec);
+
 
 enum db_cmd_type {
 	DB_PUT,  /* Insert or update new record in database */
@@ -53,18 +68,21 @@ typedef struct db_cmd {
 	enum db_cmd_type type; /* Type of the command to be executed */
     struct db_ctx* ctx;   /* Context containing database connections to be used */
     str table;            /* Name of the table to perform the command on */
-	db_drv_func_t exec[DB_PAYLOAD_MAX]; /* Array of exec functions provided by modules */
-	db_fld_t* match;      /* Fields to match */
-	db_fld_t* fld;        /* Fields to store or retrieve */
+	db_exec_func_t exec[DB_PAYLOAD_MAX]; /* Array of exec functions provided by modules */
+	db_first_func_t first[DB_PAYLOAD_MAX];
+	db_next_func_t next[DB_PAYLOAD_MAX];
+	db_fld_t* result;     /* Fields to to be returned in result */
+	db_fld_t* params;     /* Query parameters */
 } db_cmd_t;
 
 
 #define DB_SET_EXEC(db_cmd, func) do { \
-		(db_cmd)->exec[db_payload_idx] = (void*)(func);	\
+		(db_cmd)->exec[db_payload_idx] = (func); \
 } while(0)
 
 
-struct db_cmd* db_cmd(enum db_cmd_type type, struct db_ctx* ctx, char* table, db_fld_t* match, db_fld_t* fld);
+struct db_cmd* db_cmd(enum db_cmd_type type, struct db_ctx* ctx, char* table, 
+					  db_fld_t* result, db_fld_t* params);
 void db_cmd_free(struct db_cmd* cmd);
 
 int db_exec(struct db_res** res, struct db_cmd* cmd);
@@ -73,4 +91,6 @@ int db_exec(struct db_res** res, struct db_cmd* cmd);
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_CMD_H */

+ 4 - 0
db/db_con.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <string.h>
 #include <stdlib.h>
 #include "../mem/mem.h"
@@ -104,3 +106,5 @@ void db_con_free(db_con_t* con)
 	if (con->uri) db_uri_free(con->uri);
     pkg_free(con);
 }
+
+/** @} */

+ 6 - 0
db/db_con.h

@@ -29,6 +29,8 @@
 #ifndef _DB_CON_H
 #define _DB_CON_H  1
 
+/** \ingroup DB_API @{ */
+
 #include "db_gen.h"
 #include "db_ctx.h"
 #include "db_uri.h"
@@ -60,4 +62,8 @@ void db_con_free(struct db_con* con);
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_CON_H */
+
+

+ 27 - 31
db/db_ctx.c

@@ -26,33 +26,33 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <string.h>
 #include "../dprint.h"
 #include "../mem/mem.h"
 #include "db.h"
 #include "db_ctx.h"
 
-
 static struct db_ctx_data* db_ctx_data(str* module, db_drv_t* data)
 {
-	struct db_ctx_data* res;
+	struct db_ctx_data* newp;
 
-	res = (struct db_ctx_data*)pkg_malloc(sizeof(struct db_ctx_data));
-	if (res == NULL) goto error;
-	memset(res, '\0', sizeof(struct db_ctx_data));
+	newp = (struct db_ctx_data*)pkg_malloc(sizeof(struct db_ctx_data));
+	if (newp == NULL) goto error;
+	memset(newp, '\0', sizeof(struct db_ctx_data));
 
-	res->module.s = pkg_malloc(module->len);
-	if (res->module.s == NULL) goto error;
-
-	memcpy(res->module.s, module->s, module->len);
-	res->module.len = module->len;
-	res->data = data;
+	newp->module.s = pkg_malloc(module->len);
+	if (newp->module.s == NULL) goto error;
 
+	memcpy(newp->module.s, module->s, module->len);
+	newp->module.len = module->len;
+	newp->data = data;
 	return res;
 
  error:
-	ERR("db_ctx_data: No memory left\n");
-	if (res) pkg_free(res);
+	ERR("No memory left\n");
+	if (newp) pkg_free(newp);
 	return NULL;
 }
 
@@ -77,8 +77,6 @@ db_ctx_t* db_ctx(const char* id)
     memset(r, '\0', sizeof(db_ctx_t));
 	if (db_gen_init(&r->gen) < 0) goto error;
 
-	DBLIST_INIT(&r->con);
-
 	r->id.len = strlen(id);
 	r->id.s = pkg_malloc(r->id.len + 1);
 	if (r->id.s == NULL) goto error;
@@ -106,7 +104,7 @@ db_ctx_t* db_ctx(const char* id)
  */
 void db_ctx_free(db_ctx_t* ctx)
 {
-	db_con_t* con, *tmp_con;
+	int i;
 	struct db_ctx_data* ptr, *ptr2;
 
     if (ctx == NULL) return;
@@ -119,17 +117,15 @@ void db_ctx_free(db_ctx_t* ctx)
 	/* Disconnect all connections */
 	db_disconnect(ctx);
 
-	/* Destroy the list of all connections */
-	DBLIST_FOREACH_SAFE(con, &ctx->con, tmp_con) {
- 		DBLIST_REMOVE_HEAD(&ctx->con);
-		db_con_free(con);
+	for(i = 0; i < ctx->con_n; i++) {
+		db_con_free(ctx->con[i]);
 	}
 
 	/* Dispose all driver specific data structures as well as
 	 * the data structures in db_ctx_data linked list
 	 */
 	SLIST_FOREACH_SAFE(ptr, &ctx->data, next, ptr2) {
-		if (ptr->data) ptr->data->free(ptr->data);
+		if (ptr->data) ptr->data->free((void*)ptr, ptr->data);
 		db_ctx_data_free(ptr);
 	}
 	/* Clear all pointers to attached data structures because we have
@@ -210,7 +206,7 @@ int db_add_db(db_ctx_t* ctx, const char* uri)
 			/* We failed to create db_ctx_data for this payload so we have
 			 * to dispose it manually here before bailing out.
 			 */
-			((struct db_drv*)DB_GET_PAYLOAD(ctx))->free(DB_GET_PAYLOAD(ctx));
+			((struct db_drv*)DB_GET_PAYLOAD(ctx))->free((void*)ctx, DB_GET_PAYLOAD(ctx));
 			goto error;
 		}
 
@@ -230,9 +226,7 @@ int db_add_db(db_ctx_t* ctx, const char* uri)
 	con = db_con(ctx, parsed_uri);
 	if (con == NULL) goto error;
 
-	DBLIST_INSERT_TAIL(&ctx->con, con);
-	ctx->con_n++;
-
+	ctx->con[ctx->con_n++] = con;
 	return 0;
 
  error:
@@ -247,10 +241,10 @@ int db_add_db(db_ctx_t* ctx, const char* uri)
  */
 int db_connect(db_ctx_t* ctx)
 {
-	db_con_t* con;
+	int i;
 
-	DBLIST_FOREACH(con, &ctx->con) {
-		if (con->connect && con->connect(con) < 0) return -1;
+	for(i = 0; i < ctx->con_n; i++) {
+		if (ctx->con[i]->connect && ctx->con[i]->connect(ctx->con[i]) < 0) return -1;
 	}
 	return 0;
 }
@@ -262,9 +256,11 @@ int db_connect(db_ctx_t* ctx)
  */
 void db_disconnect(db_ctx_t* ctx)
 {
-	db_con_t* con;
+	int i;
 
-	DBLIST_FOREACH(con, &ctx->con) {
-		if (con->disconnect) con->disconnect(con);
+	for(i = 0; i < ctx->con_n; i++) {
+		if (ctx->con[i]->disconnect) ctx->con[i]->disconnect(ctx->con[i]);
 	}
 }
+
+/** @} */

+ 6 - 1
db/db_ctx.h

@@ -29,6 +29,8 @@
 #ifndef _DB_CTX_H
 #define _DB_CTX_H  1
 
+/** \ingroup DB_API @{ */
+
 #include "../str.h"
 #include "../list.h"
 #include "db_drv.h"
@@ -41,6 +43,7 @@ extern "C" {
 
 struct db_ctx;
 
+
 /* This structure is stored in a linked list inside db_ctx
  * and is used to lookup driver-specific data based on module
  * name. A driver can have multiple connections in a context but
@@ -60,7 +63,7 @@ typedef struct db_ctx {
 	str id;          /* Text id of the context */
 	int con_n;       /* Number of connections in the context */
 	SLIST_HEAD(, db_ctx_data) data;
-   	DBLIST_HEAD(db_ctx_con) con;  /* The list of all connections within the context */
+	struct db_con* con[DB_PAYLOAD_MAX];
 } db_ctx_t;
 
 	
@@ -101,4 +104,6 @@ void db_disconnect(struct db_ctx* ctx);
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_CTX_H */

+ 4 - 0
db/db_drv.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <string.h>
 #include <stdlib.h>
 #include "../mem/mem.h"
@@ -101,3 +103,5 @@ int db_drv_call(str* module, char* func_name, void* db_struct, int offset)
 		return 1;
 	}
 }
+
+/** @} */

+ 7 - 1
db/db_drv.h

@@ -29,16 +29,20 @@
 #ifndef _DB_DRV_H
 #define _DB_DRV_H  1
 
+/** \ingroup DB_API @{ */
+
 #include "../str.h"
 #include "../list.h"
+#include "db_gen.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
 struct db_drv;
+struct db_gen;
 
-typedef void db_drv_free_t(struct db_drv* data);
+typedef void db_drv_free_t(struct db_gen* db_struct, struct db_drv* payload);
 
 
 /*
@@ -81,4 +85,6 @@ int db_drv_call(str* module, char* func_name, void* db_struct, int offset);
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_DRV_H */

+ 16 - 8
db/db_fld.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <string.h>
 #include "../mem/mem.h"
 #include "../dprint.h"
@@ -36,7 +38,6 @@ int db_fld_init(db_fld_t* fld, size_t n)
 {
 	int i;
 
-	memset(fld, '\0', sizeof(db_fld_t) * n);
 	for(i = 0; i < n; i++) {
 		if (db_gen_init(&fld[i].gen) < 0) return -1;
 	}
@@ -44,6 +45,16 @@ int db_fld_init(db_fld_t* fld, size_t n)
 }
 
 
+void db_fld_close(db_fld_t* fld, size_t n)
+{
+	int i;
+
+	for(i = 0; i < n; i++) {
+		db_gen_free(&fld[i].gen);
+	}
+}
+
+
 db_fld_t* db_fld(size_t n)
 {
 	db_fld_t* r;
@@ -53,6 +64,8 @@ db_fld_t* db_fld(size_t n)
 		ERR("db_fld: No memory left\n");
 		return NULL;
 	}
+	memset(r, '\0', sizeof(db_fld_t) * n);
+
 	if (db_fld_init(r, n) < 0) goto error;
 	return r;
 
@@ -67,13 +80,8 @@ db_fld_t* db_fld(size_t n)
 
 void db_fld_free(db_fld_t* fld, size_t n)
 {
-    int i;
-    if (!fld || !n) return;
-
-	for(i = 0; i < n; i++) {
-		db_gen_free(&fld[i].gen);
-		if (fld[i].name.s) pkg_free(fld[i].name.s);
-	}
+	db_fld_close(fld, n);
 	pkg_free(fld);
 }
 
+/** @} */

+ 12 - 3
db/db_fld.h

@@ -29,6 +29,8 @@
 #ifndef _DB_FLD_H
 #define _DB_FLD_H  1
 
+/** \ingroup DB_API @{ */
+
 #include <time.h>
 #include "../str.h"
 #include "db_gen.h"
@@ -64,7 +66,7 @@ enum db_flags {
 
 typedef struct db_fld {
 	db_gen_t gen;  /* Generic part of the structure */
-    str name;
+    char* name;
     enum db_fld_type type;
     unsigned int flags;
     union {
@@ -72,7 +74,7 @@ typedef struct db_fld {
 		float        flt;    /* float value */
 		double       dbl;    /* double value */
 		time_t       time;   /* unix time value */
-		const char*  cstr;   /* NULL terminated string */
+		char*  cstr;         /* NULL terminated string */
 		str          str;    /* str string value */
 		str          blob;   /* Blob data */
 		unsigned int bitmap; /* Bitmap data type, 32 flags, should be enough */ 
@@ -81,13 +83,20 @@ typedef struct db_fld {
 	enum db_fld_op op;
 } db_fld_t;
 
+#define DB_FLD_LAST(fld) ((fld).name == NULL)
+#define DB_FLD_EMPTY(fld) ((fld) == NULL || (fld)[0].name == NULL)
 
 struct db_fld* db_fld(size_t n);
-int db_fld_init(struct db_fld* fld, size_t n);
 void db_fld_free(struct db_fld* fld, size_t n);
 
+int db_fld_init(struct db_fld* fld, size_t n);
+void db_fld_release(struct db_fld* fld, size_t n);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_FLD_H */

+ 5 - 1
db/db_gen.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <string.h>
 #include "db_gen.h"
 
@@ -52,6 +54,8 @@ void db_gen_free(db_gen_t* gen)
 
 	/* Dispose all the attached data structures */
 	for(i = 0; i < DB_PAYLOAD_MAX && gen->data[i]; i++) {
-		if (gen->data[i]) gen->data[i]->free(gen->data[i]);
+		if (gen->data[i]) gen->data[i]->free(gen, gen->data[i]);
 	}
 }
+
+/** @} */

+ 7 - 5
db/db_gen.h

@@ -29,6 +29,10 @@
 #ifndef _DB_GEN_H
 #define _DB_GEN_H  1
 
+/** \ingroup DB_API 
+ * @{ 
+ */
+
 #include "../str.h"
 #include "../list.h"
 #include "db_drv.h"
@@ -38,11 +42,6 @@ extern "C" {
 #endif /* __cplusplus */
 
 
-/*
- * Operations on top of linked-lists of generic DB API structures
- */
-
-
 /*
  * Declare a list of DB API structures with given structure
  * name
@@ -72,6 +71,7 @@ extern "C" {
 #define DBLIST_INIT(head) \
 	STAILQ_INIT(head)
 
+#define	DBLIST_FIRST(head) SLIST_FIRST(head)
 
 /*
  * Insert a new DB API structure at the beginning of the
@@ -207,4 +207,6 @@ void db_gen_free(struct db_gen* gen);
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_GEN_H */

+ 4 - 0
db/db_pool.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <unistd.h>
 #include <string.h>
 #include "../dprint.h"
@@ -113,3 +115,5 @@ int db_pool_remove(db_pool_entry_t* entry)
 	SLIST_REMOVE(&db_pool, entry, db_pool_entry, next);
 	return 1;
 }
+
+/** @} */

+ 6 - 0
db/db_pool.h

@@ -29,6 +29,10 @@
 #ifndef _DB_POOL_H
 #define _DB_POOL_H  1
 
+/** \ingroup DB_API 
+ * @{ 
+ */
+
 #include <sys/types.h>
 #include "db_drv.h"
 #include "../list.h"
@@ -89,4 +93,6 @@ int db_pool_remove(struct db_pool_entry* entry);
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_POOL_H */

+ 9 - 2
db/db_rec.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <stdlib.h>
 #include <string.h>
 #include "../dprint.h"
@@ -33,7 +35,7 @@
 #include "db_rec.h"
 
 
-db_rec_t* db_rec(void)
+db_rec_t* db_rec(db_res_t* res, db_fld_t* fld)
 {
     db_rec_t* r;
 
@@ -41,10 +43,12 @@ db_rec_t* db_rec(void)
     if (r == NULL) goto err;
     memset(r, '\0', sizeof(db_rec_t));
 	if (db_gen_init(&r->gen) < 0) goto err;
+	r->res = res;
+	r->fld = fld;
     return r;
 
  err:
-    ERR("db_rec: Cannot create db_rec structure\n");
+    ERR("Cannot create db_rec structure\n");
 	if (r) {
 		db_gen_free(&r->gen);
 		pkg_free(r);
@@ -56,6 +60,9 @@ db_rec_t* db_rec(void)
 void db_rec_free(db_rec_t* r)
 {
     if (r == NULL) return;
+	/* Do not release fld here, it points to an array in db_cmd */
 	db_gen_free(&r->gen);
     pkg_free(r);
 }
+
+/** @} */

+ 9 - 1
db/db_rec.h

@@ -29,7 +29,11 @@
 #ifndef _DB_REC_H
 #define _DB_REC_H  1
 
+/** \ingroup DB_API @{ */
+
 #include "db_gen.h"
+#include "db_res.h"
+#include "db_fld.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -37,13 +41,17 @@ extern "C" {
 
 typedef struct db_rec {
 	db_gen_t gen; /* Generic part of the structure */
+	struct db_res* res; /* Result this record belongs to */
+	db_fld_t* fld; /* Array of all fields in the record */
 } db_rec_t;
 
-struct db_rec* db_rec(void);
+struct db_rec* db_rec(struct db_res* res, db_fld_t* fld);
 void db_rec_free(struct db_rec* rec);
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_REC_H */

+ 32 - 0
db/db_res.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <string.h>
 #include "../dprint.h"
 #include "../mem/mem.h"
@@ -35,17 +37,26 @@
 db_res_t* db_res(db_cmd_t* cmd)
 {
     db_res_t* r;
+	int ret;
 
     r = (db_res_t*)pkg_malloc(sizeof(db_res_t));
     if (r == NULL) goto err;
 	memset(r, '\0', sizeof(db_res_t));
 	if (db_gen_init(&r->gen) < 0) goto err;
     r->cmd = cmd;
+
+	ret = db_drv_call(&cmd->ctx->con[db_payload_idx]->uri->scheme, 
+					  "db_res", r, db_payload_idx);
+	if (ret < 0) goto err;
+
+	r->cur_rec = db_rec(r, cmd->result);
+	if (r->cur_rec == NULL) goto err;
     return r;
 
  err:
     ERR("db_res: Cannot create db_res structure\n");
 	if (r) {
+		if (r->cur_rec) db_rec_free(r->cur_rec);
 		db_gen_free(&r->gen);
 		pkg_free(r);
 	}
@@ -57,5 +68,26 @@ void db_res_free(db_res_t* r)
 {
     if (r == NULL) return;
 	db_gen_free(&r->gen);
+	if (r->cur_rec) db_rec_free(r->cur_rec);
     pkg_free(r);
 }
+
+
+db_rec_t* db_first(db_res_t* res)
+{
+	if (res->cmd->first[0](res) != 0) {
+		return NULL;
+	}
+	return res->cur_rec;
+}
+
+
+db_rec_t* db_next(db_res_t* res)
+{
+	if (res->cmd->next[0](res) != 0) {
+		return NULL;
+	}
+	return res->cur_rec;
+}
+
+/** @} */

+ 12 - 0
db/db_res.h

@@ -29,7 +29,12 @@
 #ifndef _DB_RES_H
 #define _DB_RES_H  1
 
+/** \ingroup DB_API 
+ * @{ 
+ */
+
 #include "db_gen.h"
+#include "db_rec.h"
 #include "db_cmd.h"
 
 #ifdef __cplusplus
@@ -38,14 +43,21 @@ extern "C" {
 
 typedef struct db_res {
 	db_gen_t gen;       /* Generic part of the structure */
+	struct db_rec* cur_rec;  /* Currently active record in the result */
     struct db_cmd* cmd; /* Command that produced the result */
 } db_res_t;
 
 struct db_res* db_res(struct db_cmd* cmd);
 void db_res_free(struct db_res* res);
 
+struct db_rec* db_first(struct db_res* res);
+
+struct db_rec* db_next(struct db_res* res);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_RES_H */

+ 4 - 0
db/db_uri.c

@@ -26,6 +26,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+/** \ingroup DB_API @{ */
+
 #include <string.h>
 #include "../dprint.h"
 #include "../mem/mem.h"
@@ -121,3 +123,5 @@ void db_uri_free(db_uri_t* uri)
     if (uri->scheme.s) pkg_free(uri->scheme.s);
     pkg_free(uri);
 }
+
+/** @} */

+ 4 - 0
db/db_uri.h

@@ -29,6 +29,8 @@
 #ifndef _DB_URI_H
 #define _DB_URI_H  1
 
+/** \ingroup DB_API @{ */
+
 #include "../str.h"
 #include "db_gen.h"
 
@@ -63,4 +65,6 @@ db_uri_cmp_t db_uri_cmp;
 }
 #endif /* __cplusplus */
 
+/** @} */
+
 #endif /* _DB_URI_H */