<p>George Joseph <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/8919">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Kevin Harwell: Looks good to me, but someone else must approve
Joshua Colp: Looks good to me, but someone else must approve
Matthew Fredrickson: Looks good to me, approved
George Joseph: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">cdr_mysql: split mysql init out of my_load_module<br><br>Split out mysql connection parts to a separate my_connect_db().<br><br>ASTERISK-27572<br><br>Change-Id: If2ee676056067cc693ff08be68ee4944bf35b49f<br>---<br>M addons/cdr_mysql.c<br>1 file changed, 134 insertions(+), 127 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/addons/cdr_mysql.c b/addons/cdr_mysql.c<br>index 97ebdf2..b194b7e 100644<br>--- a/addons/cdr_mysql.c<br>+++ b/addons/cdr_mysql.c<br>@@ -448,6 +448,137 @@<br> return 0;<br> }<br> <br>+/** Connect to MySQL. Initializes the connection.<br>+ *<br>+ * * Assumes the read-write lock for columns is held.<br>+ * * Caller should allocate and free cfg<br>+ * */<br>+static int my_connect_db(struct ast_config *cfg)<br>+{<br>+ struct ast_variable *var;<br>+ char *temp;<br>+ MYSQL_ROW row;<br>+ MYSQL_RES *result;<br>+ char sqldesc[128];<br>+#if MYSQL_VERSION_ID >= 50013<br>+ my_bool my_bool_true = 1;<br>+#endif<br>+<br>+ mysql_init(&mysql);<br>+<br>+ if (timeout && mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout) != 0) {<br>+ ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));<br>+ }<br>+<br>+#if MYSQL_VERSION_ID >= 50013<br>+ /* Add option for automatic reconnection */<br>+ if (mysql_options(&mysql, MYSQL_OPT_RECONNECT, &my_bool_true) != 0) {<br>+ ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));<br>+ }<br>+#endif<br>+<br>+ if ((ssl_ca && ast_str_strlen(ssl_ca)) || (ssl_cert && ast_str_strlen(ssl_cert)) || (ssl_key && ast_str_strlen(ssl_key))) {<br>+ mysql_ssl_set(&mysql,<br>+ ssl_key ? ast_str_buffer(ssl_key) : NULL,<br>+ ssl_cert ? ast_str_buffer(ssl_cert) : NULL,<br>+ ssl_ca ? ast_str_buffer(ssl_ca) : NULL,<br>+ NULL, NULL);<br>+ }<br>+ temp = dbsock && ast_str_strlen(dbsock) ? ast_str_buffer(dbsock) : NULL;<br>+<br>+ configure_connection_charset();<br>+<br>+ if (!mysql_real_connect(&mysql, ast_str_buffer(hostname), ast_str_buffer(dbuser), ast_str_buffer(password), ast_str_buffer(dbname), dbport, temp, ssl_ca && ast_str_strlen(ssl_ca) ? CLIENT_SSL : 0)) {<br>+ ast_log(LOG_ERROR, "Failed to connect to mysql database %s on %s.\n", ast_str_buffer(dbname), ast_str_buffer(hostname));<br>+ connected = 0;<br>+ records = 0;<br>+ } else {<br>+ ast_debug(1, "Successfully connected to MySQL database.\n");<br>+ connected = 1;<br>+ records = 0;<br>+ connect_time = time(NULL);<br>+<br>+ /* Get table description */<br>+ snprintf(sqldesc, sizeof(sqldesc), "DESC %s", dbtable ? ast_str_buffer(dbtable) : "cdr");<br>+ if (mysql_query(&mysql, sqldesc)) {<br>+ ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");<br>+ mysql_close(&mysql);<br>+ connected = 0;<br>+<br>+ return AST_MODULE_LOAD_DECLINE;<br>+ }<br>+<br>+ if (!(result = mysql_store_result(&mysql))) {<br>+ ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");<br>+ mysql_close(&mysql);<br>+ connected = 0;<br>+<br>+ return AST_MODULE_LOAD_DECLINE;<br>+ }<br>+<br>+ while ((row = mysql_fetch_row(result))) {<br>+ struct column *entry;<br>+ char *cdrvar = "", *staticvalue = "";<br>+<br>+ ast_debug(1, "Got a field '%s' of type '%s'\n", row[0], row[1]);<br>+ /* Check for an alias or a static value */<br>+ for (var = ast_variable_browse(cfg, "columns"); var; var = var->next) {<br>+ if (strncmp(var->name, "alias", 5) == 0 && strcasecmp(var->value, row[0]) == 0 ) {<br>+ char *alias = ast_strdupa(var->name + 5);<br>+ cdrvar = ast_strip(alias);<br>+ ast_verb(3, "Found alias %s for column %s\n", cdrvar, row[0]);<br>+ break;<br>+ } else if (strncmp(var->name, "static", 6) == 0 && strcasecmp(var->value, row[0]) == 0) {<br>+ char *item = ast_strdupa(var->name + 6);<br>+ item = ast_strip(item);<br>+ if (item[0] == '"' && item[strlen(item) - 1] == '"') {<br>+ /* Remove surrounding quotes */<br>+ item[strlen(item) - 1] = '\0';<br>+ item++;<br>+ }<br>+ staticvalue = item;<br>+ }<br>+ }<br>+<br>+ entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(row[0]) + 1 + strlen(cdrvar) + 1 + strlen(staticvalue) + 1 + strlen(row[1]) + 1);<br>+ if (!entry) {<br>+ ast_log(LOG_ERROR, "Out of memory creating entry for column '%s'\n", row[0]);<br>+ mysql_free_result(result);<br>+ return AST_MODULE_LOAD_DECLINE;<br>+ }<br>+<br>+ entry->name = (char *)entry + sizeof(*entry);<br>+ strcpy(entry->name, row[0]);<br>+<br>+ if (!ast_strlen_zero(cdrvar)) {<br>+ entry->cdrname = entry->name + strlen(row[0]) + 1;<br>+ strcpy(entry->cdrname, cdrvar);<br>+ } else { /* Point to same place as the column name */<br>+ entry->cdrname = (char *)entry + sizeof(*entry);<br>+ }<br>+<br>+ if (!ast_strlen_zero(staticvalue)) {<br>+ entry->staticvalue = entry->cdrname + strlen(entry->cdrname) + 1;<br>+ strcpy(entry->staticvalue, staticvalue);<br>+ ast_debug(1, "staticvalue length: %d\n", (int) strlen(staticvalue) );<br>+ entry->type = entry->staticvalue + strlen(entry->staticvalue) + 1;<br>+ } else {<br>+ entry->type = entry->cdrname + strlen(entry->cdrname) + 1;<br>+ }<br>+ strcpy(entry->type, row[1]);<br>+<br>+ ast_debug(1, "Entry name '%s'\n", entry->name);<br>+ ast_debug(1, " cdrname '%s'\n", entry->cdrname);<br>+ ast_debug(1, " static '%s'\n", entry->staticvalue);<br>+ ast_debug(1, " type '%s'\n", entry->type);<br>+<br>+ AST_LIST_INSERT_TAIL(&columns, entry, list);<br>+ }<br>+ mysql_free_result(result);<br>+ }<br>+ return AST_MODULE_LOAD_SUCCESS;<br>+}<br>+<br> static int my_load_module(int reload)<br> {<br> int res;<br>@@ -458,14 +589,7 @@<br> * rescan the table layout. */<br> struct ast_flags config_flags = { 0 };<br> struct column *entry;<br>- char *temp;<br> struct ast_str *compat;<br>- MYSQL_ROW row;<br>- MYSQL_RES *result;<br>- char sqldesc[128];<br>-#if MYSQL_VERSION_ID >= 50013<br>- my_bool my_bool_true = 1;<br>-#endif<br> <br> /* Cannot use a conditionally different flag, because the table layout may<br> * have changed, which is not detectable by config file change detection,<br>@@ -562,129 +686,12 @@<br> ast_debug(1, "Got DB charset of %s\n", ast_str_buffer(dbcharset));<br> }<br> <br>- mysql_init(&mysql);<br>-<br>- if (timeout && mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout) != 0) {<br>- ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));<br>- }<br>-<br>-#if MYSQL_VERSION_ID >= 50013<br>- /* Add option for automatic reconnection */<br>- if (mysql_options(&mysql, MYSQL_OPT_RECONNECT, &my_bool_true) != 0) {<br>- ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));<br>- }<br>-#endif<br>-<br>- if ((ssl_ca && ast_str_strlen(ssl_ca)) || (ssl_cert && ast_str_strlen(ssl_cert)) || (ssl_key && ast_str_strlen(ssl_key))) {<br>- mysql_ssl_set(&mysql,<br>- ssl_key ? ast_str_buffer(ssl_key) : NULL,<br>- ssl_cert ? ast_str_buffer(ssl_cert) : NULL,<br>- ssl_ca ? ast_str_buffer(ssl_ca) : NULL,<br>- NULL, NULL);<br>- }<br>- temp = dbsock && ast_str_strlen(dbsock) ? ast_str_buffer(dbsock) : NULL;<br>-<br>- configure_connection_charset();<br>-<br>- if (!mysql_real_connect(&mysql, ast_str_buffer(hostname), ast_str_buffer(dbuser), ast_str_buffer(password), ast_str_buffer(dbname), dbport, temp, ssl_ca && ast_str_strlen(ssl_ca) ? CLIENT_SSL : 0)) {<br>- ast_log(LOG_ERROR, "Failed to connect to mysql database %s on %s.\n", ast_str_buffer(dbname), ast_str_buffer(hostname));<br>- connected = 0;<br>- records = 0;<br>- } else {<br>- ast_debug(1, "Successfully connected to MySQL database.\n");<br>- connected = 1;<br>- records = 0;<br>- connect_time = time(NULL);<br>-<br>- /* Get table description */<br>- snprintf(sqldesc, sizeof(sqldesc), "DESC %s", dbtable ? ast_str_buffer(dbtable) : "cdr");<br>- if (mysql_query(&mysql, sqldesc)) {<br>- ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");<br>- mysql_close(&mysql);<br>- connected = 0;<br>- AST_RWLIST_UNLOCK(&columns);<br>- ast_config_destroy(cfg);<br>- free_strings();<br>-<br>- return AST_MODULE_LOAD_DECLINE;<br>- }<br>-<br>- if (!(result = mysql_store_result(&mysql))) {<br>- ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");<br>- mysql_close(&mysql);<br>- connected = 0;<br>- AST_RWLIST_UNLOCK(&columns);<br>- ast_config_destroy(cfg);<br>- free_strings();<br>-<br>- return AST_MODULE_LOAD_DECLINE;<br>- }<br>-<br>- while ((row = mysql_fetch_row(result))) {<br>- struct column *entry;<br>- char *cdrvar = "", *staticvalue = "";<br>-<br>- ast_debug(1, "Got a field '%s' of type '%s'\n", row[0], row[1]);<br>- /* Check for an alias or a static value */<br>- for (var = ast_variable_browse(cfg, "columns"); var; var = var->next) {<br>- if (strncmp(var->name, "alias", 5) == 0 && strcasecmp(var->value, row[0]) == 0 ) {<br>- char *alias = ast_strdupa(var->name + 5);<br>- cdrvar = ast_strip(alias);<br>- ast_verb(3, "Found alias %s for column %s\n", cdrvar, row[0]);<br>- break;<br>- } else if (strncmp(var->name, "static", 6) == 0 && strcasecmp(var->value, row[0]) == 0) {<br>- char *item = ast_strdupa(var->name + 6);<br>- item = ast_strip(item);<br>- if (item[0] == '"' && item[strlen(item) - 1] == '"') {<br>- /* Remove surrounding quotes */<br>- item[strlen(item) - 1] = '\0';<br>- item++;<br>- }<br>- staticvalue = item;<br>- }<br>- }<br>-<br>- entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(row[0]) + 1 + strlen(cdrvar) + 1 + strlen(staticvalue) + 1 + strlen(row[1]) + 1);<br>- if (!entry) {<br>- ast_log(LOG_ERROR, "Out of memory creating entry for column '%s'\n", row[0]);<br>- res = -1;<br>- break;<br>- }<br>-<br>- entry->name = (char *)entry + sizeof(*entry);<br>- strcpy(entry->name, row[0]);<br>-<br>- if (!ast_strlen_zero(cdrvar)) {<br>- entry->cdrname = entry->name + strlen(row[0]) + 1;<br>- strcpy(entry->cdrname, cdrvar);<br>- } else { /* Point to same place as the column name */<br>- entry->cdrname = (char *)entry + sizeof(*entry);<br>- }<br>-<br>- if (!ast_strlen_zero(staticvalue)) {<br>- entry->staticvalue = entry->cdrname + strlen(entry->cdrname) + 1;<br>- strcpy(entry->staticvalue, staticvalue);<br>- ast_debug(1, "staticvalue length: %d\n", (int) strlen(staticvalue) );<br>- entry->type = entry->staticvalue + strlen(entry->staticvalue) + 1;<br>- } else {<br>- entry->type = entry->cdrname + strlen(entry->cdrname) + 1;<br>- }<br>- strcpy(entry->type, row[1]);<br>-<br>- ast_debug(1, "Entry name '%s'\n", entry->name);<br>- ast_debug(1, " cdrname '%s'\n", entry->cdrname);<br>- ast_debug(1, " static '%s'\n", entry->staticvalue);<br>- ast_debug(1, " type '%s'\n", entry->type);<br>-<br>- AST_LIST_INSERT_TAIL(&columns, entry, list);<br>- }<br>- mysql_free_result(result);<br>- }<br>+ res = my_connect_db(cfg);<br> AST_RWLIST_UNLOCK(&columns);<br> ast_config_destroy(cfg);<br>- if (res < 0) {<br>+ if (res != AST_MODULE_LOAD_SUCCESS) {<br> my_unload_module(0);<br>- return AST_MODULE_LOAD_DECLINE;<br>+ return res;<br> }<br> <br> if (!reload) {<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/8919">change 8919</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/8919"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: If2ee676056067cc693ff08be68ee4944bf35b49f </div>
<div style="display:none"> Gerrit-Change-Number: 8919 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Tzafrir Cohen <tzafrir.cohen@xorcom.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Matthew Fredrickson <creslin@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Oron Peled <oron.peled@xorcom.com> </div>
<div style="display:none"> Gerrit-Reviewer: Sean Bright <sean.bright@gmail.com> </div>