<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-hlr/+/15929">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">db.c: code dup: add db_run_statements() for arrays of statements<br><br>The db bootstrap as well as the upgrade code all execute a number of<br>statements, and have massive code dup around each statement execution. Instead<br>have one db_run_statements() that takes an array of strings and runs all.<br><br>Change-Id: I2721dfc0a9aadcc7f5ac81a1c0fa87452098996f<br>---<br>M src/db.c<br>1 file changed, 34 insertions(+), 74 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-hlr refs/changes/29/15929/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/db.c b/src/db.c</span><br><span>index d2564e6..75ca889 100644</span><br><span>--- a/src/db.c</span><br><span>+++ b/src/db.c</span><br><span>@@ -201,28 +201,38 @@</span><br><span>        talloc_free(dbc);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int db_bootstrap(struct db_context *dbc)</span><br><span style="color: hsl(120, 100%, 40%);">+static int db_run_statements(struct db_context *dbc, const char **statements, size_t statements_count)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        int rc;</span><br><span>      int i;</span><br><span style="color: hsl(0, 100%, 40%);">-  for (i = 0; i < ARRAY_SIZE(stmt_bootstrap_sql); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-               int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 0; i < statements_count; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+           const char *stmt_str = statements[i];</span><br><span>                sqlite3_stmt *stmt;</span><br><span style="color: hsl(0, 100%, 40%);">-             rc = sqlite3_prepare_v2(dbc->db, stmt_bootstrap_sql[i], -1, &stmt, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            rc = sqlite3_prepare_v2(dbc->db, stmt_str, -1, &stmt, NULL);</span><br><span>          if (rc != SQLITE_OK) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", stmt_bootstrap_sql[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", stmt_str);</span><br><span>                         return rc;</span><br><span>           }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>            rc = sqlite3_step(stmt);</span><br><span>             db_remove_reset(stmt);</span><br><span>               sqlite3_finalize(stmt);</span><br><span>              if (rc != SQLITE_DONE) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGP(DDB, LOGL_ERROR, "Cannot bootstrap database: SQL error: (%d) %s,"</span><br><span style="color: hsl(0, 100%, 40%);">-                             " during stmt '%s'",</span><br><span style="color: hsl(0, 100%, 40%);">-                          rc, sqlite3_errmsg(dbc->db), stmt_bootstrap_sql[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGP(DDB, LOGL_ERROR, "SQL error: (%d) %s, during stmt '%s'",</span><br><span style="color: hsl(120, 100%, 40%);">+                            rc, sqlite3_errmsg(dbc->db), stmt_str);</span><br><span>                      return rc;</span><br><span>           }</span><br><span>    }</span><br><span style="color: hsl(120, 100%, 40%);">+     return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int db_bootstrap(struct db_context *dbc)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int rc = db_run_statements(dbc, stmt_bootstrap_sql, ARRAY_SIZE(stmt_bootstrap_sql));</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rc != SQLITE_DONE) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DDB, LOGL_ERROR, "Cannot bootstrap database\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span>    return SQLITE_OK;</span><br><span> }</span><br><span> </span><br><span>@@ -263,75 +273,38 @@</span><br><span> static int</span><br><span> db_upgrade_v1(struct db_context *dbc)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  sqlite3_stmt *stmt;</span><br><span>  int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- const char *update_stmt_sql = "ALTER TABLE subscriber ADD COLUMN last_lu_seen TIMESTAMP default NULL";</span><br><span style="color: hsl(0, 100%, 40%);">-        const char *set_schema_version_sql = "PRAGMA user_version = 1";</span><br><span style="color: hsl(120, 100%, 40%);">+     const char *statements[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+          "ALTER TABLE subscriber ADD COLUMN last_lu_seen TIMESTAMP default NULL",</span><br><span style="color: hsl(120, 100%, 40%);">+            "PRAGMA user_version = 1",</span><br><span style="color: hsl(120, 100%, 40%);">+  };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  rc = sqlite3_prepare_v2(dbc->db, update_stmt_sql, -1, &stmt, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (rc != SQLITE_OK) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", update_stmt_sql);</span><br><span style="color: hsl(0, 100%, 40%);">-             return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = sqlite3_step(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-        db_remove_reset(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-  sqlite3_finalize(stmt);</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = db_run_statements(dbc, statements, ARRAY_SIZE(statements));</span><br><span>     if (rc != SQLITE_DONE) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version %d\n", 1);</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version 1\n");</span><br><span>              return rc;</span><br><span>   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = sqlite3_prepare_v2(dbc->db, set_schema_version_sql, -1, &stmt, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (rc != SQLITE_OK) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", set_schema_version_sql);</span><br><span style="color: hsl(0, 100%, 40%);">-              return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = sqlite3_step(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (rc != SQLITE_DONE)</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version %d\n", 1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     db_remove_reset(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-  sqlite3_finalize(stmt);</span><br><span>      return rc;</span><br><span> }</span><br><span> </span><br><span> static int db_upgrade_v2(struct db_context *dbc)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    sqlite3_stmt *stmt;</span><br><span>  int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- const char *update_stmt_sql = "ALTER TABLE subscriber ADD COLUMN imei VARCHAR(14)";</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *set_schema_version_sql = "PRAGMA user_version = 2";</span><br><span style="color: hsl(120, 100%, 40%);">+     const char *statements[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+          "ALTER TABLE subscriber ADD COLUMN imei VARCHAR(14)",</span><br><span style="color: hsl(120, 100%, 40%);">+               "PRAGMA user_version = 2",</span><br><span style="color: hsl(120, 100%, 40%);">+  };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  rc = sqlite3_prepare_v2(dbc->db, update_stmt_sql, -1, &stmt, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (rc != SQLITE_OK) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", update_stmt_sql);</span><br><span style="color: hsl(0, 100%, 40%);">-             return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = sqlite3_step(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-        db_remove_reset(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-  sqlite3_finalize(stmt);</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = db_run_statements(dbc, statements, ARRAY_SIZE(statements));</span><br><span>     if (rc != SQLITE_DONE) {</span><br><span>             LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version 2\n");</span><br><span>              return rc;</span><br><span>   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = sqlite3_prepare_v2(dbc->db, set_schema_version_sql, -1, &stmt, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (rc != SQLITE_OK) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", set_schema_version_sql);</span><br><span style="color: hsl(0, 100%, 40%);">-              return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = sqlite3_step(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (rc != SQLITE_DONE)</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version 2\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- db_remove_reset(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-  sqlite3_finalize(stmt);</span><br><span>      return rc;</span><br><span> }</span><br><span> </span><br><span> static int db_upgrade_v3(struct db_context *dbc)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-    sqlite3_stmt *stmt;</span><br><span>  int rc;</span><br><span> </span><br><span>  /* A newer SQLite version would allow simply 'ATLER TABLE subscriber RENAME COLUMN hlr_number TO msc_number'.</span><br><span>@@ -442,23 +415,10 @@</span><br><span>                "PRAGMA user_version = 3",</span><br><span>         };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  int i;</span><br><span style="color: hsl(0, 100%, 40%);">-  for (i = 0; i < ARRAY_SIZE(statements); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-               const char *update_stmt_sql = statements[i];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = sqlite3_prepare_v2(dbc->db, update_stmt_sql, -1, &stmt, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-              if (rc != SQLITE_OK) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  LOGP(DDB, LOGL_ERROR, "Unable to prepare SQL statement '%s'\n", update_stmt_sql);</span><br><span style="color: hsl(0, 100%, 40%);">-                     return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-               rc = sqlite3_step(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-                db_remove_reset(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-          sqlite3_finalize(stmt);</span><br><span style="color: hsl(0, 100%, 40%);">-         if (rc != SQLITE_DONE) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version 3\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                 return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = db_run_statements(dbc, statements, ARRAY_SIZE(statements));</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc != SQLITE_DONE) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version 3\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return rc;</span><br><span>   }</span><br><span>    return rc;</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-hlr/+/15929">change 15929</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.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.osmocom.org/c/osmo-hlr/+/15929"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-hlr </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I2721dfc0a9aadcc7f5ac81a1c0fa87452098996f </div>
<div style="display:none"> Gerrit-Change-Number: 15929 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>