<h1>Project "FreeSWITCH Source" received a push.</h1>

<h2>branch: master updated</h2>
<pre>
       via: bcb2262fdc48b36bd2e6bfe45adcbaecd1d091ee (commit)
      from: f0a31e1bfff2d49d97bc0ee83627c426fa311bfc (commit)


</pre>= COMMIT LOG ===========================================================
<div class="highlight"><pre>committer: Daniel Swarbrick
comments: 
major factor of pgsql field handling

<span style="color: #000080; font-weight: bold">diff --git a/conf/autoload_configs/cdr_pg_csv.conf.xml b/conf/autoload_configs/cdr_pg_csv.conf.xml</span>
<span style="color: #000080; font-weight: bold">index 427bf2d..4fec817 100644</span>
<span style="color: #A00000">--- a/conf/autoload_configs/cdr_pg_csv.conf.xml</span>
<span style="color: #00A000">+++ b/conf/autoload_configs/cdr_pg_csv.conf.xml</span>
<span style="color: #800080; font-weight: bold">@@ -16,10 +16,25 @@</span>
 
     &lt;!-- This is like the info app but after the call is hung up --&gt;
     &lt;!--&lt;param name=&quot;debug&quot; value=&quot;true&quot;/&gt;--&gt;
<span style="color: #A00000">-</span>
<span style="color: #A00000">-    &lt;param name=&quot;default-template&quot; value=&quot;example&quot;/&gt;</span>
   &lt;/settings&gt;
<span style="color: #A00000">-  &lt;templates&gt;</span>
<span style="color: #A00000">-    &lt;template name=&quot;example&quot;&gt;&quot;${local_ip_v4}&quot;,&quot;${caller_id_name}&quot;,&quot;${caller_id_number}&quot;,&quot;${destination_number}&quot;,&quot;${context}&quot;,&quot;${start_stamp}&quot;,&quot;${answer_stamp}&quot;,&quot;${end_stamp}&quot;,&quot;${duration}&quot;,&quot;${billsec}&quot;,&quot;${hangup_cause}&quot;,&quot;${uuid}&quot;,&quot;${bleg_uuid}&quot;,&quot;${accountcode}&quot;,&quot;${read_codec}&quot;,&quot;${write_codec}&quot;,&quot;${sip_hangup_disposition}&quot;,&quot;${ani}&quot;&lt;/template&gt;</span>
<span style="color: #A00000">-  &lt;/templates&gt;</span>
<span style="color: #00A000">+  &lt;schema&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;local_ip_v4&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;caller_id_name&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;caller_id_number&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;destination_number&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;context&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;start_stamp&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;answer_stamp&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;end_stamp&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;duration&quot; quote=&quot;false&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;billsec&quot; quote=&quot;false&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;hangup_cause&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;uuid&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;bleg_uuid&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;accountcode&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;read_codec&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;field var=&quot;write_codec&quot;/&gt;</span>
<span style="color: #00A000">+    &lt;!-- &lt;field var=&quot;sip_hangup_disposition&quot;/&gt; --&gt;</span>
<span style="color: #00A000">+    &lt;!-- &lt;field var=&quot;ani&quot;/&gt; --&gt;</span>
<span style="color: #00A000">+  &lt;/schema&gt;</span>
 &lt;/configuration&gt;
<span style="color: #000080; font-weight: bold">diff --git a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c</span>
<span style="color: #000080; font-weight: bold">index 1ec56bd..51194f4 100644</span>
<span style="color: #A00000">--- a/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c</span>
<span style="color: #00A000">+++ b/src/mod/event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c</span>
<span style="color: #800080; font-weight: bold">@@ -59,28 +59,34 @@ typedef struct {</span>
         switch_mutex_t *mutex;
 } cdr_fd_t;
 
<span style="color: #A00000">-const char *default_template =</span>
<span style="color: #A00000">-        &quot;\&quot;${local_ip_v4}\&quot;,\&quot;${caller_id_name}\&quot;,\&quot;${caller_id_number}\&quot;,\&quot;${destination_number}\&quot;,\&quot;${context}\&quot;,\&quot;${start_stamp}\&quot;,&quot;</span>
<span style="color: #A00000">-        &quot;\&quot;${answer_stamp}\&quot;,\&quot;${end_stamp}\&quot;,\&quot;${duration}\&quot;,\&quot;${billsec}\&quot;,\&quot;${hangup_cause}\&quot;,\&quot;${uuid}\&quot;,\&quot;${bleg_uuid}\&quot;,\&quot;${accountcode}\&quot;,&quot;</span>
<span style="color: #A00000">-        &quot;\&quot;${read_codec}\&quot;,\&quot;${write_codec}\&quot;&quot;;</span>
<span style="color: #00A000">+typedef struct {</span>
<span style="color: #00A000">+        char *col_name;</span>
<span style="color: #00A000">+        char *var_name;</span>
<span style="color: #00A000">+        switch_bool_t quote;</span>
<span style="color: #00A000">+        switch_bool_t not_null;</span>
<span style="color: #00A000">+} cdr_field_t;</span>
<span style="color: #00A000">+</span>
<span style="color: #00A000">+typedef struct {</span>
<span style="color: #00A000">+        char *columns;</span>
<span style="color: #00A000">+        cdr_field_t fields[1];</span>
<span style="color: #00A000">+} db_schema_t;</span>
 
 static struct {
         switch_memory_pool_t *pool;
         switch_hash_t *fd_hash;
<span style="color: #A00000">-        switch_hash_t *template_hash;</span>
         int shutdown;
         char *db_info;
         char *db_table;
<span style="color: #00A000">+        db_schema_t *db_schema;</span>
         PGconn *db_connection;
<span style="color: #00A000">+        switch_mutex_t *db_mutex;</span>
         int db_online;
         cdr_leg_t legs;
         char *spool_dir;
         spool_format_t spool_format;
         int rotate;
         int debug;
<span style="color: #A00000">-        char *default_template;</span>
<span style="color: #A00000">-        switch_mutex_t *db_mutex;</span>
<span style="color: #A00000">-} globals = { 0 };</span>
<span style="color: #00A000">+} globals;</span>
 
 static switch_xml_config_enum_item_t config_opt_cdr_leg_enum[] = {
         {&quot;a&quot;, CDR_LEG_A},
<span style="color: #800080; font-weight: bold">@@ -110,7 +116,6 @@ static switch_xml_config_item_t config_settings[] = {</span>
         /* key, type, flags, ptr, default_value, data, syntax, helptext */
         SWITCH_CONFIG_ITEM_STRING_STRDUP(&quot;db-info&quot;, CONFIG_RELOADABLE, &amp;globals.db_info, &quot;dbname=cdr&quot;, NULL, NULL),
         SWITCH_CONFIG_ITEM_STRING_STRDUP(&quot;db-table&quot;, CONFIG_RELOADABLE, &amp;globals.db_table, &quot;cdr&quot;, NULL, NULL),
<span style="color: #A00000">-        SWITCH_CONFIG_ITEM_STRING_STRDUP(&quot;default-template&quot;, CONFIG_RELOADABLE, &amp;globals.default_template, &quot;default&quot;, NULL, NULL),</span>
         SWITCH_CONFIG_ITEM(&quot;legs&quot;, SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &amp;globals.legs, (void *) CDR_LEG_A, &amp;config_opt_cdr_leg_enum, &quot;a|b|ab&quot;, NULL),
         SWITCH_CONFIG_ITEM(&quot;spool-format&quot;, SWITCH_CONFIG_ENUM, CONFIG_RELOADABLE, &amp;globals.spool_format, (void *) SPOOL_FORMAT_CSV, &amp;config_opt_spool_format_enum, &quot;csv|sql&quot;, &quot;Disk spool format to use if SQL insert fails.&quot;),
         SWITCH_CONFIG_ITEM(&quot;rotate-on-hup&quot;, SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &amp;globals.rotate, SWITCH_FALSE, NULL, NULL, NULL),
<span style="color: #800080; font-weight: bold">@@ -239,135 +244,13 @@ static void spool_cdr(const char *path, const char *log_line)</span>
         switch_safe_free(log_line_lf);
 }
 
<span style="color: #A00000">-static switch_status_t insert_cdr(const char * const template, const char * const cdr)</span>
<span style="color: #00A000">+static switch_status_t insert_cdr(const char *values)</span>
 {
<span style="color: #A00000">-        char *columns, *values;</span>
<span style="color: #A00000">-        char *p, *q;</span>
<span style="color: #A00000">-        unsigned vlen;</span>
<span style="color: #A00000">-        char *nullValues, *temp, *tp;</span>
<span style="color: #A00000">-        int nullCounter = 0, charCounter = 0;</span>
         char *sql = NULL, *path = NULL;
         PGresult *res;
 
<span style="color: #A00000">-        if (!template || !*template || !cdr || !*cdr) {</span>
<span style="color: #A00000">-                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, &quot;Bad parameter\n&quot;);</span>
<span style="color: #A00000">-                return SWITCH_STATUS_FALSE;</span>
<span style="color: #A00000">-        }</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        /* Build comma-separated list of field names by dropping $ { } ; chars */</span>
<span style="color: #A00000">-        switch_strdup(columns, template);</span>
<span style="color: #A00000">-        for (p = columns, q = columns; *p; ++p) {</span>
<span style="color: #A00000">-                switch (*p) {</span>
<span style="color: #A00000">-                        case &#39;$&#39;: case &#39;&quot;&#39;: case &#39;{&#39;: case &#39;}&#39;: case &#39;;&#39;:</span>
<span style="color: #A00000">-                                break;</span>
<span style="color: #A00000">-                        default:</span>
<span style="color: #A00000">-                                *q++ = *p;</span>
<span style="color: #A00000">-                }</span>
<span style="color: #A00000">-        }</span>
<span style="color: #A00000">-        *q = &#39;\0&#39;;</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        /*</span>
<span style="color: #A00000">-         * In the expanded vars, replace double quotes (&quot;) with single quotes (&#39;)</span>
<span style="color: #A00000">-         * for correct PostgreSQL syntax, and replace semi-colon with space to</span>
<span style="color: #A00000">-         * prevent SQL injection attacks</span>
<span style="color: #A00000">-         */</span>
<span style="color: #A00000">-        switch_strdup(values, cdr);</span>
<span style="color: #A00000">-        for (p = values; *p; ++p) {</span>
<span style="color: #A00000">-                switch(*p) {</span>
<span style="color: #A00000">-                        case &#39;&quot;&#39;:</span>
<span style="color: #A00000">-                                *p = &#39;\&#39;&#39;;</span>
<span style="color: #A00000">-                                break;</span>
<span style="color: #A00000">-                        case &#39;;&#39;:</span>
<span style="color: #A00000">-                                *p = &#39; &#39;;</span>
<span style="color: #A00000">-                                break;</span>
<span style="color: #A00000">-                }</span>
<span style="color: #A00000">-        }</span>
<span style="color: #A00000">-        vlen = p - values;</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        /*</span>
<span style="color: #A00000">-         * Patch for changing empty strings (&#39;&#39;) in the expanded variables to</span>
<span style="color: #A00000">-         * PostgreSQL null</span>
<span style="color: #A00000">-         */</span>
<span style="color: #A00000">-        for (p = values; *p; ++p) {</span>
<span style="color: #A00000">-                if (*p == &#39;,&#39;) {</span>
<span style="color: #A00000">-                        if (charCounter == 0) {</span>
<span style="color: #A00000">-                                nullCounter++;</span>
<span style="color: #A00000">-                        }</span>
<span style="color: #A00000">-                        charCounter = 0;</span>
<span style="color: #A00000">-                } else if (*p != &#39; &#39; &amp;&amp; *p != &#39;\&#39;&#39;) {</span>
<span style="color: #A00000">-                        charCounter++;</span>
<span style="color: #A00000">-                }</span>
<span style="color: #A00000">-        }</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        if (charCounter == 0) {</span>
<span style="color: #A00000">-                nullCounter++;</span>
<span style="color: #A00000">-        }</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        nullCounter *= 4;</span>
<span style="color: #A00000">-        vlen += nullCounter;</span>
<span style="color: #A00000">-        switch_zmalloc(nullValues, strlen(values) + nullCounter + 1);</span>
<span style="color: #A00000">-        charCounter = 0;</span>
<span style="color: #A00000">-        temp = nullValues;</span>
<span style="color: #A00000">-        tp = nullValues;</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        for (p = values; *p; ++tp, ++p) {</span>
<span style="color: #A00000">-                if (*p == &#39;,&#39;) {</span>
<span style="color: #A00000">-                        if (charCounter == 0) {</span>
<span style="color: #A00000">-                                temp++;</span>
<span style="color: #A00000">-                                *temp = &#39;n&#39;;</span>
<span style="color: #A00000">-                                temp++;</span>
<span style="color: #A00000">-                                if (temp == tp) tp++;</span>
<span style="color: #A00000">-                                *temp = &#39;u&#39;;</span>
<span style="color: #A00000">-                                temp++;</span>
<span style="color: #A00000">-                                if (temp == tp) tp++;</span>
<span style="color: #A00000">-                                *temp = &#39;l&#39;;</span>
<span style="color: #A00000">-                                temp++;</span>
<span style="color: #A00000">-                                if (temp == tp) tp++;</span>
<span style="color: #A00000">-                                *temp = &#39;l&#39;;</span>
<span style="color: #A00000">-                                temp++;</span>
<span style="color: #A00000">-                                while (temp != tp) {</span>
<span style="color: #A00000">-                                        *temp = &#39; &#39;;</span>
<span style="color: #A00000">-                                        temp++;</span>
<span style="color: #A00000">-                                }</span>
<span style="color: #A00000">-                        }</span>
<span style="color: #A00000">-                        charCounter = 0;</span>
<span style="color: #A00000">-                        temp = tp;</span>
<span style="color: #A00000">-                } else if (*p != &#39; &#39; &amp;&amp; *p != &#39;\&#39;&#39;) {</span>
<span style="color: #A00000">-                        charCounter++;</span>
<span style="color: #A00000">-                }</span>
<span style="color: #A00000">-                *tp = *p;</span>
<span style="color: #A00000">-        }</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        if (charCounter == 0) {</span>
<span style="color: #A00000">-                temp++;</span>
<span style="color: #A00000">-                *temp = &#39;n&#39;;</span>
<span style="color: #A00000">-                temp++;</span>
<span style="color: #A00000">-                if (temp == tp) tp++;</span>
<span style="color: #A00000">-                *temp = &#39;u&#39;;</span>
<span style="color: #A00000">-                temp++;</span>
<span style="color: #A00000">-                if (temp == tp) tp++;</span>
<span style="color: #A00000">-                *temp = &#39;l&#39;;</span>
<span style="color: #A00000">-                temp++;</span>
<span style="color: #A00000">-                if (temp == tp) tp++;</span>
<span style="color: #A00000">-                *temp = &#39;l&#39;;</span>
<span style="color: #A00000">-                temp++;</span>
<span style="color: #A00000">-                while (temp != tp) {</span>
<span style="color: #A00000">-                        *temp = &#39; &#39;;</span>
<span style="color: #A00000">-                        temp++;</span>
<span style="color: #A00000">-                }</span>
<span style="color: #A00000">-        }</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        charCounter = 0;</span>
<span style="color: #A00000">-        temp = tp;</span>
<span style="color: #A00000">-        *tp = 0;</span>
<span style="color: #A00000">-        tp = values;</span>
<span style="color: #A00000">-        values = nullValues;</span>
<span style="color: #A00000">-        switch_safe_free(tp);</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        sql = switch_mprintf(&quot;INSERT INTO %s (%s) VALUES (%s);&quot;, globals.db_table, columns, values);</span>
<span style="color: #00A000">+        sql = switch_mprintf(&quot;INSERT INTO %s (%s) VALUES (%s);&quot;, globals.db_table, globals.db_schema-&gt;columns, values);</span>
         assert(sql);
<span style="color: #A00000">-        switch_safe_free(columns);</span>
<span style="color: #A00000">-        switch_safe_free(values);</span>
 
         if (globals.debug) {
                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, &quot;Query: \&quot;%s\&quot;\n&quot;, sql);
<span style="color: #800080; font-weight: bold">@@ -415,7 +298,7 @@ static switch_status_t insert_cdr(const char * const template, const char * cons</span>
         } else {
                 path = switch_mprintf(&quot;%s%scdr-spool.csv&quot;, globals.spool_dir, SWITCH_PATH_SEPARATOR);
                 assert(path);
<span style="color: #A00000">-                spool_cdr(path, cdr);</span>
<span style="color: #00A000">+                spool_cdr(path, values);</span>
         }
 
         switch_safe_free(path);
<span style="color: #800080; font-weight: bold">@@ -428,8 +311,10 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)</span>
 {
         switch_channel_t *channel = switch_core_session_get_channel(session);
         switch_status_t status = SWITCH_STATUS_SUCCESS;
<span style="color: #A00000">-        const char *template_str = NULL;</span>
<span style="color: #A00000">-        char *expanded_vars = NULL;</span>
<span style="color: #00A000">+        char *values = NULL, *tmp = NULL, *pq_var = NULL;</span>
<span style="color: #00A000">+        const char *var = NULL;</span>
<span style="color: #00A000">+        cdr_field_t *cdr_field = NULL;</span>
<span style="color: #00A000">+        switch_size_t len, offset;</span>
 
         if (globals.shutdown) {
                 return SWITCH_STATUS_SUCCESS;
<span style="color: #800080; font-weight: bold">@@ -465,24 +350,40 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)</span>
                 }
         }
 
<span style="color: #A00000">-        template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template);</span>
<span style="color: #00A000">+        switch_zmalloc(values, 1);</span>
<span style="color: #00A000">+        offset = 0;</span>
 
<span style="color: #A00000">-        if (!template_str) {</span>
<span style="color: #A00000">-                template_str = default_template;</span>
<span style="color: #A00000">-        }</span>
<span style="color: #00A000">+        for (cdr_field = globals.db_schema-&gt;fields; cdr_field-&gt;var_name; cdr_field++) {</span>
<span style="color: #00A000">+                if ((var = switch_channel_get_variable(channel, cdr_field-&gt;var_name))) {</span>
<span style="color: #00A000">+                        /* Allocate sufficient buffer for PQescapeString */</span>
<span style="color: #00A000">+                        len = strlen(var);</span>
<span style="color: #00A000">+                        tmp = switch_core_session_alloc(session, len * 2 + 1);</span>
<span style="color: #00A000">+                        PQescapeString(tmp, var, len);</span>
<span style="color: #00A000">+                        var = tmp;</span>
<span style="color: #00A000">+                }</span>
 
<span style="color: #A00000">-        expanded_vars = switch_channel_expand_variables(channel, template_str);</span>
<span style="color: #00A000">+                if (cdr_field-&gt;quote) {</span>
<span style="color: #00A000">+                        if ((cdr_field-&gt;not_null == SWITCH_FALSE) &amp;&amp; zstr(var)) {</span>
<span style="color: #00A000">+                                pq_var = switch_mprintf(&quot;null,&quot;, var);</span>
<span style="color: #00A000">+                        } else {</span>
<span style="color: #00A000">+                                pq_var = switch_mprintf(&quot;&#39;%s&#39;,&quot;, var);</span>
<span style="color: #00A000">+                        }</span>
<span style="color: #00A000">+                } else {</span>
<span style="color: #00A000">+                        pq_var = switch_mprintf(&quot;%s,&quot;, var);</span>
<span style="color: #00A000">+                }</span>
 
<span style="color: #A00000">-        if (!expanded_vars) {</span>
<span style="color: #A00000">-                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, &quot;Error expanding CDR variables.\n&quot;);</span>
<span style="color: #A00000">-                return SWITCH_STATUS_FALSE;</span>
<span style="color: #00A000">+                /* Resize values buffer to accomodate next var */</span>
<span style="color: #00A000">+                len = strlen(pq_var);</span>
<span style="color: #00A000">+                tmp = realloc(values, offset + len);</span>
<span style="color: #00A000">+                values = tmp;</span>
<span style="color: #00A000">+                memcpy(values + offset, pq_var, len);</span>
<span style="color: #00A000">+                switch_safe_free(pq_var);</span>
<span style="color: #00A000">+                offset += len;</span>
         }
<span style="color: #00A000">+        *(values + --offset) = &#39;\0&#39;;</span>
 
<span style="color: #A00000">-        insert_cdr(template_str, expanded_vars);</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        if (expanded_vars != template_str) {</span>
<span style="color: #A00000">-                switch_safe_free(expanded_vars);</span>
<span style="color: #A00000">-        }</span>
<span style="color: #00A000">+        insert_cdr(values);</span>
<span style="color: #00A000">+        switch_safe_free(values);</span>
 
         return status;
 }
<span style="color: #800080; font-weight: bold">@@ -532,9 +433,13 @@ static switch_state_handler_table_t state_handlers = {</span>
 
 static switch_status_t load_config(switch_memory_pool_t *pool)
 {
<span style="color: #A00000">-        char *cf = &quot;cdr_pg_csv.conf&quot;;</span>
<span style="color: #A00000">-        switch_xml_t cfg, xml, settings, param;</span>
         switch_status_t status = SWITCH_STATUS_SUCCESS;
<span style="color: #00A000">+        char *cf = &quot;cdr_pg_csv.conf&quot;, *ptr;</span>
<span style="color: #00A000">+        switch_xml_t cfg, xml, schema, field;</span>
<span style="color: #00A000">+        const char *attr;</span>
<span style="color: #00A000">+        int num_fields = 0;</span>
<span style="color: #00A000">+        switch_size_t len = 0;</span>
<span style="color: #00A000">+        cdr_field_t *cdr_field;</span>
 
         if (globals.db_online) {
                 PQfinish(globals.db_connection);
<span style="color: #800080; font-weight: bold">@@ -544,32 +449,69 @@ static switch_status_t load_config(switch_memory_pool_t *pool)</span>
 
         memset(&amp;globals, 0, sizeof(globals));
         switch_core_hash_init(&amp;globals.fd_hash, pool);
<span style="color: #A00000">-        switch_core_hash_init(&amp;globals.template_hash, pool);</span>
         switch_mutex_init(&amp;globals.db_mutex, SWITCH_MUTEX_NESTED, pool);
 
         globals.pool = pool;
 
<span style="color: #A00000">-        switch_core_hash_insert(globals.template_hash, &quot;default&quot;, default_template);</span>
<span style="color: #A00000">-        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;Adding default template.\n&quot;);</span>
<span style="color: #A00000">-        globals.legs = CDR_LEG_A;</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-        if (switch_xml_config_parse_module_settings(&quot;cdr_pg_csv.conf&quot;, SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) {</span>
<span style="color: #00A000">+        if (switch_xml_config_parse_module_settings(cf, SWITCH_FALSE, config_settings) != SWITCH_STATUS_SUCCESS) {</span>
                 return SWITCH_STATUS_FALSE;
         }
 
         if ((xml = switch_xml_open_cfg(cf, &amp;cfg, NULL))) {
<span style="color: #A00000">-                if ((settings = switch_xml_child(cfg, &quot;templates&quot;))) {</span>
<span style="color: #A00000">-                        for (param = switch_xml_child(settings, &quot;template&quot;); param; param = param-&gt;next) {</span>
<span style="color: #A00000">-                                char *var = (char *) switch_xml_attr(param, &quot;name&quot;);</span>
<span style="color: #A00000">-                                if (var) {</span>
<span style="color: #A00000">-                                        char *tpl;</span>
<span style="color: #A00000">-                                        tpl = switch_core_strdup(pool, param-&gt;txt);</span>
<span style="color: #A00000">-</span>
<span style="color: #A00000">-                                        switch_core_hash_insert(globals.template_hash, var, tpl);</span>
<span style="color: #A00000">-                                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, &quot;Adding template %s.\n&quot;, var);</span>
<span style="color: #00A000">+                if ((schema = switch_xml_child(cfg, &quot;schema&quot;))) {</span>
<span style="color: #00A000">+                        /* Count fields in schema so we can calculate required buffer size */</span>
<span style="color: #00A000">+                        for (field = switch_xml_child(schema, &quot;field&quot;); field; field = field-&gt;next) {</span>
<span style="color: #00A000">+                                if (switch_xml_attr(field, &quot;var&quot;)) {</span>
<span style="color: #00A000">+                                        num_fields++;</span>
                                 }
                         }
<span style="color: #00A000">+</span>
<span style="color: #00A000">+                        globals.db_schema = switch_core_alloc(pool, (num_fields + 1) * sizeof(cdr_field_t));</span>
<span style="color: #00A000">+                        cdr_field = globals.db_schema-&gt;fields;</span>
<span style="color: #00A000">+</span>
<span style="color: #00A000">+                        for (field = switch_xml_child(schema, &quot;field&quot;); field; field = field-&gt;next) {</span>
<span style="color: #00A000">+                                if ((attr = switch_xml_attr(field, &quot;var&quot;))) {</span>
<span style="color: #00A000">+                                        cdr_field-&gt;var_name = switch_core_strdup(pool, attr);</span>
<span style="color: #00A000">+</span>
<span style="color: #00A000">+                                        /* Assume SQL column name is the same as FreeSWITCH channel var name, unless specified otherwise */</span>
<span style="color: #00A000">+                                        if ((attr = switch_xml_attr(field, &quot;column&quot;))) {</span>
<span style="color: #00A000">+                                                cdr_field-&gt;col_name = switch_core_strdup(pool, attr);</span>
<span style="color: #00A000">+                                        } else {</span>
<span style="color: #00A000">+                                                cdr_field-&gt;col_name = switch_core_strdup(pool, cdr_field-&gt;var_name);</span>
<span style="color: #00A000">+                                        }</span>
<span style="color: #00A000">+</span>
<span style="color: #00A000">+                                        /* Assume all fields should be quoted (treated as strings), unless specified otherwise */</span>
<span style="color: #00A000">+                                        if ((attr = switch_xml_attr(field, &quot;quote&quot;)) &amp;&amp; !strncmp(attr, &quot;false&quot;, 5)) {</span>
<span style="color: #00A000">+                                                cdr_field-&gt;quote = SWITCH_FALSE;</span>
<span style="color: #00A000">+                                        } else {</span>
<span style="color: #00A000">+                                                cdr_field-&gt;quote = SWITCH_TRUE;</span>
<span style="color: #00A000">+                                        }</span>
<span style="color: #00A000">+</span>
<span style="color: #00A000">+                                        /* Assume all fields allow SQL nulls, unless specified otherwise */</span>
<span style="color: #00A000">+                                        if ((attr = switch_xml_attr(field, &quot;not-null&quot;)) &amp;&amp; !strncmp(attr, &quot;true&quot;, 4)) {</span>
<span style="color: #00A000">+                                                cdr_field-&gt;not_null = SWITCH_TRUE;</span>
<span style="color: #00A000">+                                        } else {</span>
<span style="color: #00A000">+                                                cdr_field-&gt;not_null = SWITCH_FALSE;</span>
<span style="color: #00A000">+                                        }</span>
<span style="color: #00A000">+</span>
<span style="color: #00A000">+                                        len += strlen(cdr_field-&gt;col_name) + 1;</span>
<span style="color: #00A000">+                                        cdr_field++;</span>
<span style="color: #00A000">+                                }</span>
<span style="color: #00A000">+                        }</span>
<span style="color: #00A000">+                        cdr_field-&gt;var_name = 0;</span>
<span style="color: #00A000">+</span>
<span style="color: #00A000">+                        globals.db_schema-&gt;columns = switch_core_alloc(pool, len);</span>
<span style="color: #00A000">+                        ptr = globals.db_schema-&gt;columns;</span>
<span style="color: #00A000">+                        for (cdr_field = globals.db_schema-&gt;fields; cdr_field-&gt;col_name; cdr_field++) {</span>
<span style="color: #00A000">+                                len = strlen(cdr_field-&gt;col_name);</span>
<span style="color: #00A000">+                                memcpy(ptr, cdr_field-&gt;col_name, len);</span>
<span style="color: #00A000">+                                ptr += len;</span>
<span style="color: #00A000">+                                *ptr = &#39;,&#39;;</span>
<span style="color: #00A000">+                                ptr++;</span>
<span style="color: #00A000">+                        }</span>
<span style="color: #00A000">+                        *--ptr = &#39;\0&#39;;</span>
                 }
<span style="color: #00A000">+</span>
                 switch_xml_free(xml);
         }
 
<span style="color: #800080; font-weight: bold">@@ -596,7 +538,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cdr_pg_csv_load)</span>
         switch_core_add_state_handler(&amp;state_handlers);
         *module_interface = switch_loadable_module_create_module_interface(pool, modname);
 
<span style="color: #A00000">-</span>
         return status;
 }
 
</pre></div>
========================================================================<pre>

Summary of changes:
 conf/autoload_configs/cdr_pg_csv.conf.xml          |   25 ++-
 .../event_handlers/mod_cdr_pg_csv/mod_cdr_pg_csv.c |  275 ++++++++------------
 2 files changed, 128 insertions(+), 172 deletions(-)
</pre>
<p>this email was generated because of /git/your-repo.git/hooks/post-receive by the file /git-core/contrib/hooks/post-receive-email<br />
For more info, see <a href="http://blog.chomperstomp.com/?p=630">http://blog.chomperstomp.com/?p=630</a>
-- <br />
FreeSWITCH Source</p>