[asterisk-commits] ivaxer: branch ivaxer/ast_storage r275024 - /team/ivaxer/ast_storage/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jul 9 10:58:24 CDT 2010


Author: ivaxer
Date: Fri Jul  9 10:58:21 2010
New Revision: 275024

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=275024
Log:
implemented get() function of odbc storage backend (without downloading process)

Modified:
    team/ivaxer/ast_storage/res/res_storage_odbc.c

Modified: team/ivaxer/ast_storage/res/res_storage_odbc.c
URL: http://svnview.digium.com/svn/asterisk/team/ivaxer/ast_storage/res/res_storage_odbc.c?view=diff&rev=275024&r1=275023&r2=275024
==============================================================================
--- team/ivaxer/ast_storage/res/res_storage_odbc.c (original)
+++ team/ivaxer/ast_storage/res/res_storage_odbc.c Fri Jul  9 10:58:21 2010
@@ -63,10 +63,40 @@
 	char tablename[128];
 	struct odbc_obj *conn;
 	AST_RWLIST_HEAD(odbc_columns, columns) columns;
-	char path[1];
+	char pathname[1];
 };
 
+struct prepare_sql_cb_arg {
+	struct odbc_storage_pvt *ost;
+	const char *pathname;
+	const char *objectname;
+	const char *ext;
+	const char *sql;
+};
+
 static const struct ast_storage_be odbc_se;
+
+static struct ast_storage_fileobject *create_fileobject(void) {
+	struct ast_storage_fileobject *fo;
+	fo = ast_calloc(1, sizeof(struct ast_storage_fileobject));
+	if (!fo) {
+		return NULL;
+	}
+
+	AST_RWLIST_HEAD_INIT(&fo->files);
+	return fo;
+}
+
+static struct ast_storage_fileinst *create_fileinst(void) {
+	struct ast_storage_fileinst *fi;
+	fi = ast_calloc(1, sizeof(struct ast_storage_fileinst));
+	if(!fi) {
+		return NULL;
+	}
+
+	fi->fd = -1;
+	return fi;
+}
 
 static int se_release(struct ast_storage *st)
 {
@@ -131,7 +161,7 @@
 
 	ast_copy_string(pvt->odbc_class, args.class, sizeof(pvt->odbc_class));
 	ast_copy_string(pvt->tablename, args.tablename, sizeof(pvt->tablename));
-	strcpy(pvt->path, args.pathname);
+	strcpy(pvt->pathname, args.pathname);
 
 	pvt->conn = ast_odbc_request_obj(pvt->odbc_class, 0);
 	if (!pvt->conn) {
@@ -181,8 +211,181 @@
 	return st;
 }
 
+static struct ast_storage_fileinst *fetch_fileinst(SQLHSTMT stmt) {
+	SQLRETURN ret;
+	SQLSMALLINT colcount, colid, collen;
+	SQLULEN colsize;
+	SQLSMALLINT decimaldigits, nullable, datatype;
+	struct ast_storage_fileinst *fi;
+	char coltitle[128];
+	char rowdata[32];
+	char tmpfile_fmt[] = "/var/tmp/XXXXXX";
+	int fd;
+
+	ret = SQLFetch(stmt);
+	if (ret == SQL_NO_DATA) {
+		return NULL;
+	}
+	if(!SQL_SUCCEEDED(ret)) {
+		ast_log(LOG_WARNING, "SQL Fetch error!");
+		return NULL;
+	}
+
+	ret = SQLNumResultCols(stmt, &colcount);
+	if (!SQL_SUCCEEDED(ret)) {
+		ast_log(LOG_WARNING, "SQL Column Count error!");
+		return NULL;
+	}
+
+	fi = create_fileinst();
+	if(!fi) {
+		return NULL;
+	}
+
+	for (colid = 1; colid <= colcount; colid++) {
+		ret = SQLDescribeCol(stmt, colid, (SQLCHAR *)coltitle, sizeof(coltitle), &collen,
+				&datatype, &colsize, &decimaldigits, &nullable);
+		if(!SQL_SUCCEEDED(ret)) {
+			ast_log(LOG_WARNING, "SQL Describe Column error!");
+			goto error;
+		}
+		if(!strcasecmp(coltitle, "recording")) {
+			fd = mkstemp(tmpfile_fmt);
+			if (fd == -1) {
+				ast_log(LOG_WARNING, "Could not create temp file");
+				goto error;
+			}
+
+			/* TODO: Downloading */
+
+			ast_copy_string(fi->localfile, tmpfile_fmt, sizeof(fi->localfile));
+		}
+		else if(!strcasecmp(coltitle, "extension")) {
+			ret = SQLGetData(stmt, colid, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
+			if(!SQL_SUCCEEDED(ret)) {
+				ast_log(LOG_WARNING, "SQL Get Data error!");
+				goto error;
+			}
+
+			ast_copy_string(fi->ext, rowdata, sizeof(fi->ext));
+		}
+	}
+
+	return fi;
+error:
+	ast_storage_fileinst_release(fi);
+	return NULL;
+}
+
+static SQLHSTMT prepare_get_sql_cb(struct odbc_obj *obj, void *cb_arg) {
+	SQLHSTMT stmt;
+	SQLRETURN ret;
+	struct prepare_sql_cb_arg *arg = (struct prepare_sql_cb_arg *) cb_arg;
+	struct odbc_storage_pvt *ost = arg->ost;
+	const char *pathname = arg->pathname;
+	const char *objectname = arg->objectname;
+        const char *ext = arg->ext;
+	const char *sql = arg->sql;
+
+	ret = SQLAllocHandle(SQL_HANDLE_STMT, ost->conn->con, &stmt);
+	if (!SQL_SUCCEEDED(ret)) {
+		ast_log(LOG_WARNING, "SQL Alloc Handle failed!");
+		return NULL;
+	}
+
+	ret = SQLPrepare(stmt, (SQLCHAR *)sql, SQL_NTS);
+	if (!SQL_SUCCEEDED(ret)) {
+		ast_log(LOG_WARNING, "SQL Prepare failed!\n[%s]", sql);
+		SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+		return NULL;
+	}
+
+	SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(pathname), 0, (void *)pathname, 0, NULL);
+	SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(objectname), 0, (void *)objectname, 0, NULL);
+	if (ext)
+		SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(ext), 0, (void *)ext, 0, NULL);
+
+	return stmt;
+}
+
 static struct ast_storage_fileobject *se_get(struct ast_storage *st, const char *objectname, const char *exts)
 {
+	struct odbc_storage_pvt *ost = (struct odbc_storage_pvt *)st->storage_pvt;
+	struct prepare_sql_cb_arg prepare_cb_arg;
+	struct ast_storage_fileobject *fo = NULL;
+	struct ast_storage_fileinst *fi = NULL;
+	char ext[16];
+	char sql[128];
+	char *pathname;
+	SQLHSTMT stmt;
+	//char rowdata[256], coltitle[128];
+	//SQLSMALLINT colcount, collen, datatype;
+
+	if (ast_strlen_zero(objectname)) {
+		ast_log(LOG_WARNING, "objectname is null.\n");
+		return NULL;
+	}
+
+	if (exts) {
+		char *ptr;
+		ast_copy_string(ext, exts, sizeof(ext));
+		ptr = strchr(ext, '|');
+		if (ptr) {
+			*ptr = '\0';
+		}
+	}
+
+	/* 
+	 * TODO: objectname may contain relative or absolute path.
+	 */
+	pathname = ost->pathname;
+
+	if (exts) {
+		snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE pathname=? AND filename=? AND extension=?", ost->tablename);
+	}
+	else {
+		snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE pathname=? AND filename=?", ost->tablename);
+	}
+
+	memset(&prepare_cb_arg, 0, sizeof(prepare_cb_arg));
+	prepare_cb_arg.ost = ost;
+	prepare_cb_arg.sql = sql;
+	prepare_cb_arg.objectname = objectname;
+	prepare_cb_arg.pathname = pathname;
+	if (exts) {
+		prepare_cb_arg.ext = ext;
+	}
+
+	stmt = ast_odbc_prepare_and_execute(ost->conn, prepare_get_sql_cb, (void *) &prepare_cb_arg);
+	if (!stmt) {
+		ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n", sql);
+		return NULL;
+	}
+
+	while ((fi = fetch_fileinst(stmt)) != NULL) {
+		if (!fo) {
+			fo = create_fileobject();
+			if (!fo) {
+				goto error;
+			}
+
+			ast_copy_string(fo->objectname, objectname, sizeof(fo->objectname));
+			ast_copy_string(fo->pathname, pathname, sizeof(fo->pathname));
+		}
+
+		AST_RWLIST_WRLOCK(&fo->files);
+		AST_RWLIST_INSERT_TAIL(&fo->files, fi, list);
+		AST_RWLIST_UNLOCK(&fo->files);
+	}
+
+	SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+	return fo;
+
+error:
+	SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+	if (fo) {
+		ast_storage_fileobject_release(fo);
+	}
 	return NULL;
 }
 
@@ -279,12 +482,62 @@
         return AST_TEST_PASS;
 }
 
+AST_TEST_DEFINE(get_test)
+{
+	struct ast_storage *st;
+	struct ast_storage_fileobject *fo;
+	struct ast_storage_fileinst *fi;
+	int ret;
+	char uri[] = "asterisk-storage-test/storage/testpath";
+
+        switch (cmd) {
+        case TEST_INIT:
+                info->name = "get_test";
+                info->category = "main/storage/odbc";
+                info->summary = "get test";
+                info->description =
+                        "Tests the get function";
+                return AST_TEST_NOT_RUN;
+        case TEST_EXECUTE:
+                break;
+        }
+
+	st = se_create(uri);
+	if(!st) {
+		return AST_TEST_FAIL;
+	}
+
+	fo = se_get(st, "test", "wav");
+	if(!fo) {
+		return AST_TEST_FAIL;
+	}
+
+	printf("objectname: %s\n", fo->objectname);
+	printf("pathname: %s\n", fo->pathname);
+	printf("file instances:\n");
+
+	AST_RWLIST_RDLOCK(&fo->files);
+	AST_RWLIST_TRAVERSE(&fo->files, fi, list) {
+		printf("extension: %s, localfile: %s\n", fi->ext, fi->localfile);
+	}
+	AST_RWLIST_UNLOCK(&fo->files);
+
+	ast_storage_fileobject_release(fo);
+
+	ret = se_release(st);
+	if(ret) {
+		return AST_TEST_FAIL;
+	}
+
+        return AST_TEST_PASS;
+}
 #endif
 
 static int load_module(void)
 {
 #ifdef TEST_FRAMEWORK
 	AST_TEST_REGISTER(creation_test);
+	AST_TEST_REGISTER(get_test);
 #endif
 	return ast_register_storage(&odbc_se);
 }
@@ -293,6 +546,7 @@
 {
 #ifdef TEST_FRAMEWORK
 	AST_TEST_UNREGISTER(creation_test);
+	AST_TEST_UNREGISTER(get_test);
 #endif
 	return ast_unregister_storage(odbc_se.name);
 }




More information about the asterisk-commits mailing list