[asterisk-commits] ivaxer: branch ivaxer/ast_storage r281288 - in /team/ivaxer/ast_storage: incl...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Aug 8 14:09:31 CDT 2010


Author: ivaxer
Date: Sun Aug  8 14:09:27 2010
New Revision: 281288

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=281288
Log:
implemented the listdir() function of odbc storage backend

Modified:
    team/ivaxer/ast_storage/include/asterisk/storage.h
    team/ivaxer/ast_storage/main/storage.c
    team/ivaxer/ast_storage/res/res_storage_odbc.c

Modified: team/ivaxer/ast_storage/include/asterisk/storage.h
URL: http://svnview.digium.com/svn/asterisk/team/ivaxer/ast_storage/include/asterisk/storage.h?view=diff&rev=281288&r1=281287&r2=281288
==============================================================================
--- team/ivaxer/ast_storage/include/asterisk/storage.h (original)
+++ team/ivaxer/ast_storage/include/asterisk/storage.h Sun Aug  8 14:09:27 2010
@@ -48,10 +48,7 @@
 	AST_RWLIST_ENTRY(ast_storage_fileobject) list;
 };
 
-struct ast_storage_dirobject {
-	char objectpath[256];
-	AST_RWLIST_HEAD(, ast_storage_fileobject) fileobjects;
-};
+AST_RWLIST_HEAD(ast_storage_fileobjects, ast_storage_fileobject);
 
 struct ast_storage_be {
 	const char *name;
@@ -62,7 +59,7 @@
 	int (*del)(struct ast_storage *st, const char *fileobject);
 	ssize_t (*read)(struct ast_storage *st, struct ast_storage_fileinst *fi, void *buf, size_t count);
 	ssize_t (*write)(struct ast_storage *st, struct ast_storage_fileinst *fi, void *buf, size_t count);
-	struct ast_storage_dirobject *(*listdir)(struct ast_storage *st, const char *objectpath);
+	struct ast_storage_fileobjects *(*listdir)(struct ast_storage *st, const char *objectpath);
 	off_t (*tell)(struct ast_storage *st, struct ast_storage_fileinst *fi);
 	off_t (*seek)(struct ast_storage *st, struct ast_storage_fileinst *fi, off_t offset, int whence);
 	int (*copy)(struct ast_storage *st, const char *from, const char *to);
@@ -120,7 +117,7 @@
  * \param st Storage instance
  * \param pathname Logical name of the path
  */
-struct ast_storage_dirobject *ast_storage_listdir(struct ast_storage *st, const char *pathname);
+struct ast_storage_fileobjects *ast_storage_listdir(struct ast_storage *st, const char *pathname);
 
 off_t ast_storage_tell(struct ast_storage *st, struct ast_storage_fileinst *fi);
 int ast_storage_seek(struct ast_storage *st, struct ast_storage_fileinst *fi, off_t offset, int whence);
@@ -131,7 +128,8 @@
 struct ast_storage_fileinst *ast_storage_fileinst_create(void);
 void ast_storage_fileinst_release(struct ast_storage_fileinst *fi);
 
-void ast_storage_dirobject_release(struct ast_storage_dirobject *dobj);
+struct ast_storage_fileobjects *ast_storage_fileobjects_create(void);
+void ast_storage_fileobjects_release(struct ast_storage_fileobjects *fobjs);
 
 int ast_storage_open(struct ast_storage_fileinst *fi, int flags);
 int ast_storage_close(struct ast_storage_fileinst *fi);

Modified: team/ivaxer/ast_storage/main/storage.c
URL: http://svnview.digium.com/svn/asterisk/team/ivaxer/ast_storage/main/storage.c?view=diff&rev=281288&r1=281287&r2=281288
==============================================================================
--- team/ivaxer/ast_storage/main/storage.c (original)
+++ team/ivaxer/ast_storage/main/storage.c Sun Aug  8 14:09:27 2010
@@ -221,7 +221,7 @@
 	return 0;
 }
 
-struct ast_storage_dirobject *ast_storage_listdir(struct ast_storage *st, const char *pathname)
+struct ast_storage_fileobjects *ast_storage_listdir(struct ast_storage *st, const char *pathname)
 {
 	return st && st->be->listdir ? st->be->listdir(st, pathname) : NULL;
 }
@@ -286,21 +286,30 @@
 	ast_free(fi);
 }
 
-void ast_storage_dirobject_release(struct ast_storage_dirobject *dobj)
+struct ast_storage_fileobjects *ast_storage_fileobjects_create(void)
+{
+	struct ast_storage_fileobjects *fobjs = ast_calloc(1, sizeof(*fobjs));
+	if(!fobjs) {
+		return NULL;
+	}
+
+	AST_RWLIST_HEAD_INIT(fobjs);
+	return fobjs;
+}
+
+void ast_storage_fileobjects_release(struct ast_storage_fileobjects *fobjs)
 {
 	struct ast_storage_fileobject *fo;
 
-	if (!dobj) {
+	if (!fobjs) {
 		return;
 	}
 
-	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&dobj->fileobjects, fo, list) {
-		AST_RWLIST_REMOVE_CURRENT(list);
+	while ((fo = AST_RWLIST_REMOVE_HEAD(fobjs, list))) {
 		ast_storage_fileobject_release(fo);
 	}
-	AST_RWLIST_TRAVERSE_SAFE_END
-
-	ast_free(dobj);
+
+	ast_free(fobjs);
 }
 
 #if 0

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=281288&r1=281287&r2=281288
==============================================================================
--- team/ivaxer/ast_storage/res/res_storage_odbc.c (original)
+++ team/ivaxer/ast_storage/res/res_storage_odbc.c Sun Aug  8 14:09:27 2010
@@ -100,6 +100,11 @@
 	const char *to_objectname;
 };
 
+struct listdir_query_data {
+	const char *sql;
+	const char *pathname;
+};
+
 static const struct ast_storage_be odbc_se;
 
 static int se_release(struct ast_storage *st)
@@ -652,8 +657,133 @@
 	return 0;
 }
 
-static struct ast_storage_dirobject *se_listdir(struct ast_storage *st, const char *pathname)
-{
+static struct ast_storage_fileobject *fetch_fileobject(SQLHSTMT stmt) {
+	SQLRETURN ret;
+	SQLSMALLINT colcount, collen;
+	SQLULEN colsize;
+	SQLSMALLINT decimaldigits, nullable, datatype;
+	struct ast_storage_fileobject *fo;
+	char coltitle[128];
+	char rowdata[32];
+
+	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;
+	}
+
+	if (colcount != 1) {
+		ast_log(LOG_WARNING, "Too many columns in result");
+		return NULL;
+	}
+
+	fo = ast_storage_fileobject_create();
+	if (!fo) {
+		return NULL;
+	}
+
+	ret = SQLDescribeCol(stmt, 1, (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, "filename")) {
+		ret = SQLGetData(stmt, 1, SQL_CHAR, rowdata, sizeof(rowdata), NULL);
+		if (!SQL_SUCCEEDED(ret)) {
+			ast_log(LOG_WARNING, "SQL Get Data error!");
+			goto error;
+		}
+
+		ast_copy_string(fo->objectname, rowdata, sizeof(fo->objectname));
+	}
+	else {
+		ast_log(LOG_WARNING, "Unknown column name");
+		goto error;
+	}
+
+	return fo;
+error:
+	ast_storage_fileobject_release(fo);
+	return NULL;
+}
+
+static SQLHSTMT prepare_listdir_query(struct odbc_obj *obj, void *arg) {
+	SQLHSTMT stmt;
+	SQLRETURN ret;
+	struct listdir_query_data *qdata = (struct listdir_query_data *) arg;
+
+	ret = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt);
+	if (!SQL_SUCCEEDED(ret)) {
+		ast_log(LOG_WARNING, "SQL Alloc Handle failed!");
+		return NULL;
+	}
+
+	ret = SQLPrepare(stmt, (SQLCHAR *)qdata->sql, SQL_NTS);
+	if (!SQL_SUCCEEDED(ret)) {
+		ast_log(LOG_WARNING, "SQL Prepare failed!\n[%s]", qdata->sql);
+		SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+		return NULL;
+	}
+
+	SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(qdata->pathname), 0, (void *)qdata->pathname, 0, NULL);
+
+	return stmt;
+}
+
+static struct ast_storage_fileobjects *se_listdir(struct ast_storage *st, const char *pathname)
+{
+	struct odbc_storage_pvt *ost = (struct odbc_storage_pvt*) st->storage_pvt;
+	struct listdir_query_data qdata;
+	struct ast_storage_fileobjects *fobjs = NULL;
+	struct ast_storage_fileobject *fo = NULL;
+	char sql[128];
+	SQLHSTMT stmt;
+
+	if (!pathname) {
+		ast_log(LOG_WARNING, "fileobject is null!\n");
+		return NULL;
+	}
+
+	snprintf(sql, sizeof(sql), "SELECT DISTINCT filename FROM %s WHERE pathname=?", ost->tablename);
+
+	qdata.sql = sql;
+	qdata.pathname = pathname;
+
+	stmt = ast_odbc_prepare_and_execute(ost->conn, prepare_listdir_query, (void *) &qdata);
+	if (!stmt) {
+		ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n", sql);
+		return NULL;
+	}
+
+	while ((fo = fetch_fileobject(stmt)) != NULL) {
+		if (!fobjs) {
+			fobjs = ast_storage_fileobjects_create();
+			if (!fobjs) {
+				goto error;
+			}
+		}
+
+		ast_copy_string(fo->pathname, pathname, sizeof(fo->pathname));
+		AST_RWLIST_INSERT_TAIL(fobjs, fo, list);
+	}
+
+	SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+	return fobjs;
+
+error:
+	ast_storage_fileobjects_release(fobjs);
+	SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 	return NULL;
 }
 
@@ -1014,6 +1144,51 @@
 
 	return AST_TEST_PASS;
 }
+
+AST_TEST_DEFINE(listdir_test)
+{
+	struct ast_storage *st;
+	struct ast_storage_fileobjects *fobjs;
+	struct ast_storage_fileobject *fo;
+	int ret;
+	const char uri[] = "asterisk-storage-test/storage/testpath";
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "listdir_test";
+		info->category = "main/storage/odbc";
+		info->summary = "listdir test";
+		info->description =
+			"Tests the listdir functions";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	st = se_create(uri);
+	if (!st) {
+		return AST_TEST_FAIL;
+	}
+
+	fobjs = se_listdir(st, "testpath");
+	if (!fobjs) {
+		ast_test_status_update(test, "listdir() failed\n");
+		return AST_TEST_FAIL;
+	}
+
+	AST_RWLIST_TRAVERSE(fobjs, fo, list) {
+		ast_test_status_update(test, "listdir(): %s/%s\n", fo->pathname, fo->objectname);
+	}
+
+	/* TODO: add checks here */
+
+	ret = se_release(st);
+	if (ret) {
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+}
 #endif
 
 static int load_module(void)
@@ -1024,6 +1199,7 @@
 	AST_TEST_REGISTER(put_test);
 	AST_TEST_REGISTER(del_test);
 	AST_TEST_REGISTER(copy_test);
+	AST_TEST_REGISTER(listdir_test);
 #endif
 	return ast_register_storage(&odbc_se);
 }
@@ -1036,6 +1212,7 @@
 	AST_TEST_UNREGISTER(put_test);
 	AST_TEST_UNREGISTER(del_test);
 	AST_TEST_UNREGISTER(copy_test);
+	AST_TEST_UNREGISTER(listdir_test);
 #endif
 	return ast_unregister_storage(odbc_se.name);
 }




More information about the asterisk-commits mailing list