[svn-commits] twilson: branch twilson/res_config_sqlite3 r334213 - /team/twilson/res_config...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Wed Aug 31 19:33:46 CDT 2011
Author: twilson
Date: Wed Aug 31 19:33:42 2011
New Revision: 334213
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=334213
Log:
Add minimal realtime_require support
Automatically adds needed columns, still need to add
requirements=warn|createclose|createtext support.
Todo: cleanup/helper functions, multiple db support, transaction option
Modified:
team/twilson/res_config_sqlite3/res/res_config_sqlite3.c
Modified: team/twilson/res_config_sqlite3/res/res_config_sqlite3.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/res_config_sqlite3/res/res_config_sqlite3.c?view=diff&rev=334213&r1=334212&r2=334213
==============================================================================
--- team/twilson/res_config_sqlite3/res/res_config_sqlite3.c (original)
+++ team/twilson/res_config_sqlite3/res/res_config_sqlite3.c Wed Aug 31 19:33:42 2011
@@ -43,6 +43,7 @@
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/paths.h"
+#include "asterisk/astobj2.h"
/*** DOCUMENTATION
@@ -478,12 +479,142 @@
return tmp;
}
+static const char *get_sqlite_column_type(int type)
+{
+ /* SQLite 3 has NULL, INTEGER, REAL, TEXT, and BLOB types. Any column other than
+ * an INTEGER PRIMARY KEY will actually store any kind of data due to its dynamic
+ * typing. When we create columns, we'll go ahead and use these base types instead
+ * of messing with column widths, etc. */
+
+ switch(type) {
+ case RQ_INTEGER1 :
+ case RQ_UINTEGER1 :
+ case RQ_INTEGER2 :
+ case RQ_UINTEGER2 :
+ case RQ_INTEGER3 :
+ case RQ_UINTEGER3 :
+ case RQ_INTEGER4 :
+ case RQ_UINTEGER4 :
+ case RQ_INTEGER8 :
+ case RQ_UINTEGER8 :
+ return "INTEGER";
+ case RQ_CHAR :
+ case RQ_DATE :
+ case RQ_DATETIME :
+ return "TEXT";
+ case RQ_FLOAT :
+ return "REAL";
+ default :
+ return "TEXT";
+ }
+
+ return "TEXT";
+}
+
+static int create_sqlite3_column(const char *table, const char *column, int type, size_t sz)
+{
+ char *sql, *errmsg;
+ const char *sqltype = get_sqlite_column_type(type);
+
+ if (!(sql = sqlite3_mprintf("ALTER TABLE %q ADD COLUMN %Q %s", table, column, sqltype))) {
+ return -1;
+ }
+
+ ast_mutex_lock(&db_lock);
+ if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
+ ast_log(LOG_WARNING, "Could not execute '%s': %s\n", sql, errmsg);
+ sqlite3_free(errmsg);
+ sqlite3_free(sql);
+ return -1;
+ }
+ ast_mutex_unlock(&db_lock);
+
+ sqlite3_free(sql);
+ ast_log(LOG_NOTICE, "Creating column '%s', type %s for table %s\n", column, sqltype, table);
+ return 0;
+}
+
+static int str_hash_fn(const void *obj, const int flags)
+{
+ return ast_str_hash((const char *) obj);
+}
+
+static int str_cmp_fn(void *obj, void *arg, int flags) {
+ return !strcasecmp((const char *) obj, (const char *) arg);
+}
+
+static int add_column_name(void *arg, int num_columns, char **values, char **columns)
+{
+ char *column;
+ struct ao2_container *cnames = arg;
+
+
+ if (!(column = ao2_alloc(strlen(values[1]) + 1, NULL))) {
+ return -1;
+ }
+
+ strcpy(column, values[1]);
+
+ ao2_link(cnames, column);
+ ao2_ref(column, -1);
+
+ return 0;
+}
+
/*!
* \retval 0 Required fields met specified standards
* \retval -1 One or more fields was missing or insufficient
*/
static int realtime_sqlite3_require(const char *database, const char *table, va_list ap)
{
+
+ /* SQLite3 columns are dynamically typed, with type affinity. Built-in functions will
+ * return the results as char * anyway. The only field that that cannot contain text
+ * data is an INTEGER PRIMARY KEY, which must be a 64-bit isigned integer. So, for
+ * the purposes here we really only care whether the column exists and not what its
+ * type or length is. */
+
+ const char *column;
+ int type;
+ size_t sz;
+ char *sql, *errmsg;
+ struct ao2_container *columns;
+
+ if (!(columns = ao2_container_alloc(31, str_hash_fn, str_cmp_fn))) {
+ return -1;
+ }
+
+ if (!(sql = sqlite3_mprintf("PRAGMA table_info(%q)", table))) {
+ ao2_ref(columns, -1);
+ return -1;
+ }
+
+ ast_mutex_lock(&db_lock);
+ if (sqlite3_exec(db, sql, add_column_name, columns, &errmsg) != SQLITE_OK) {
+ ast_mutex_unlock(&db_lock);
+ ao2_ref(columns, -1);
+ sqlite3_free(sql);
+ return -1;
+ }
+ ast_mutex_unlock(&db_lock);
+
+ sqlite3_free(sql);
+
+ while ((column = va_arg(ap, typeof(column))) && (type = va_arg(ap, typeof(type))) && (sz = va_arg(ap, typeof(sz)))) {
+ char *found;
+ if (!(found = ao2_find(columns, column, OBJ_POINTER | OBJ_UNLINK))) {
+ if (create_sqlite3_column(table, column, type, sz)) {
+ ao2_ref(columns, -1);
+ return -1;
+ }
+ } else {
+ ao2_ref(found, -1);
+ }
+ }
+
+ /* Should unlink the column names causing them to be destroyed */
+ ao2_ref(columns, -1);
+
return 0;
}
More information about the svn-commits
mailing list