@@ -225,23 +225,27 @@ static struct gsm_sms *sms_from_result_v3(dbi_result result)
{
struct gsm_sms *sms = sms_alloc();
long long unsigned int sender_id;
- struct gsm_subscriber *sender;
- const char *text, *daddr;
+ const char *text, *daddr, *extension;
const unsigned char *user_data;
- char buf[32];
+ dbi_result sender_result;
if (!sms)
return NULL;
- sms->id = dbi_result_get_ulonglong(result, "id");
-
sender_id = dbi_result_get_ulonglong(result, "sender_id");
- snprintf(buf, sizeof(buf), "%llu", sender_id);
- sender = db_get_subscriber(GSM_SUBSCRIBER_ID, buf);
- OSMO_ASSERT(sender);
- strncpy(sms->src.addr, sender->extension, sizeof(sms->src.addr)-1);
- subscr_direct_free(sender);
- sender = NULL;
+ sms->id = dbi_result_get_ulonglong(result, "id");
+
+ sender_result = dbi_conn_queryf(conn,
+ "SELECT * FROM Subscriber "
+ "WHERE id = %llu", sender_id);
+
+ if (sender_result) {
+ if (dbi_result_next_row(sender_result)) {
+ extension = dbi_result_get_string(sender_result, "extension");
+ strncpy(sms->src.addr, extension, sizeof(sms->src.addr) - 1);
+ }
+ dbi_result_free(sender_result);
+ }
sms->reply_path_req = dbi_result_get_ulonglong(result, "reply_path_req");
sms->status_rep_req = dbi_result_get_ulonglong(result, "status_rep_req");
@@ -477,16 +481,20 @@ static int check_db_revision(void)
{
dbi_result result;
const char *rev_s;
+ int db_rev = 0;
+ /* Make a query */
result = dbi_conn_query(conn,
- "SELECT value FROM Meta WHERE key='revision'");
+ "SELECT value FROM Meta "
+ "WHERE key = 'revision'");
if (!result)
return -EINVAL;
-
if (!dbi_result_next_row(result)) {
dbi_result_free(result);
return -EINVAL;
}
+
+ /* Fetch the DB schema revision */
rev_s = dbi_result_get_string(result, "value");
if (!rev_s) {
dbi_result_free(result);
@@ -494,28 +502,37 @@ static int check_db_revision(void)
}
if (!strcmp(rev_s, SCHEMA_REVISION)) {
- /* everything is fine */
- } else if (!strcmp(rev_s, "2")) {
+ /* Everything is fine */
+ dbi_result_free(result);
+ return 0;
+ }
+
+ db_rev = atoi(rev_s);
+ dbi_result_free(result);
+
+ /* Incremental migration waterfall */
+ switch (db_rev) {
+ case 2:
if (update_db_revision_2())
goto error;
- } else if (!strcmp(rev_s, "3")) {
+ case 3:
if (update_db_revision_3())
goto error;
- } else if (!strcmp(rev_s, "4")) {
+ case 4:
if (update_db_revision_4())
- goto error;
- } else {
- LOGP(DDB, LOGL_FATAL, "Invalid database schema revision '%s'.\n", rev_s);
- dbi_result_free(result);
+ goto error;
+
+ /* The end of waterfall */
+ break;
+ default:
+ LOGP(DDB, LOGL_FATAL, "Invalid database schema revision '%d'.\n", db_rev);
return -EINVAL;
}
- dbi_result_free(result);
return 0;
error:
- LOGP(DDB, LOGL_FATAL, "Failed to update database from schema revision '%s'.\n", rev_s);
- dbi_result_free(result);
+ LOGP(DDB, LOGL_FATAL, "Failed to update database from schema revision '%d'.\n", db_rev);
return -EINVAL;
}
@@ -187,6 +187,7 @@ int main()
char *alice_imsi = "3243245432345";
alice = db_create_subscriber(alice_imsi);
+ db_subscriber_alloc_tmsi(alice);
db_sync_subscriber(alice);
alice_db = db_get_subscriber(GSM_SUBSCRIBER_IMSI, alice->imsi);
COMPARE(alice, alice_db);
@@ -1,2 +1,5 @@
Going to migrate from revision 3
+[0;mMigration complete.
+[0;mGoing to migrate from revision 4
+[0;mMigration complete.
[0;m
\ No newline at end of file
In the past normal migration was possible only if the actual schema version differed from the version used in DB by 1. For example, if DB uses an old version 3 and you need to use it with the code written for version 5, the check_db_revision() will convert it to 4 and DB will still use incompatible schema version during Osmo-NITB running time. After next run it will be converted to version 5. This patch replaces a set of 'else-if' checks by a 'switch' without 'break' statements between 'case' labels (waterfall). It makes you able to migrate from current version to the latest despite any difference between them. Also fixed the sms_from_result_v3() to avoid large depth of function calls, because they can be changed in the future and lose compatibility with old table schemas. Also fixed db_test and now it is successful. Signed-off-by: Vadim Yanitskiy <axilirator@gmail.com> --- openbsc/src/libmsc/db.c | 65 ++++++++++++++++++++++++++++---------------- openbsc/tests/db/db_test.c | 1 + openbsc/tests/db/db_test.err | 3 ++ 3 files changed, 45 insertions(+), 24 deletions(-)