From patchwork Thu Mar 31 10:51:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Yanitskiy X-Patchwork-Id: 604071 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by ozlabs.org (Postfix) with ESMTP id 3qbLv832STz9sD3 for ; Thu, 31 Mar 2016 21:52:36 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=KLEJYLJz; dkim-atps=neutral Received: from lists.osmocom.org (lists.osmocom.org [144.76.43.76]) by lists.osmocom.org (Postfix) with ESMTP id 477A51C440; Thu, 31 Mar 2016 10:52:33 +0000 (UTC) X-Original-To: openbsc@lists.osmocom.org Delivered-To: openbsc@lists.osmocom.org Received: from mail-lf0-x22d.google.com (mail-lf0-x22d.google.com [IPv6:2a00:1450:4010:c07::22d]) by lists.osmocom.org (Postfix) with ESMTP id 70FA31C439 for ; Thu, 31 Mar 2016 10:52:31 +0000 (UTC) Received: by mail-lf0-x22d.google.com with SMTP id c62so56629928lfc.1 for ; Thu, 31 Mar 2016 03:52:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=gfNQ7vW+F1cUkblSYC/dhoXTG4N20mx7x9+RHYcu2BM=; b=KLEJYLJzYFAhzI94as0uDwQzHhvGEs2tyifzgA+ACpT8qUU+ETObkG1pWag/zywFos KvB0jYeQwean2m2j/otEtIBSpiN4Eo3hC28nKfCFzlgncN0G4ne04S7LDXfLk3t6KYl0 r0CAXaM7F6I1heVwOD3BAXlz1kkkl/w9JYHM8t2ZWiOwxIRljrXM1CFtaYRSecspauT0 B/Lx8+zbZjTW40wdWjWm7KSV7lXwnbDJkFSh6P8xGv69dXfzGmFGKgU/XjkrdLaXei4G 2/2/EcSjr29gl49ZWZ0UMiFG+1Po7u1grdg8oScNwduD8IWDh9ZQgNxQd+mqRkWqW1Wh iwUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=gfNQ7vW+F1cUkblSYC/dhoXTG4N20mx7x9+RHYcu2BM=; b=LP4mqL1E6Mn4Jw8R7WacbP+3REy9BBiJVpEK6+wLU/cFbXXP/RwdD0tfdIz05wTfL+ bN+9e66cjVYGqyCnwJuyr6/Bq71Aq75ZEuHCi8ERDq7583oD24OcKca6kGxGPDkxqyWs 0ygEBSZ2VYP7kudw20ksi39iHutNdtHCRJQpbXdQy5fLMcqahNUSihP9V9vEKTTIH2ob 7zCaeznesSNBOsCLU3tCsXhcNMTAkdaGhwvhCElfL0wtRSR1jhSAHzJDN5yxznltmrBp asXMsNjTc7ZevbBVmL8fqKUqyjEk7oJ9jGWDsMG/kLljPsXnkmJTKFxIrxiWDn+00j+3 9B2Q== X-Gm-Message-State: AD7BkJJTsgyyu2Vlqe9l8hKP2R+aaxTWaQ+EOm/zINIMiw/KXJ7L+obnvez9KKufxCQSrw== X-Received: by 10.25.168.67 with SMTP id r64mr5338032lfe.104.1459421551540; Thu, 31 Mar 2016 03:52:31 -0700 (PDT) Received: from DELL.lan ([212.164.216.34]) by smtp.gmail.com with ESMTPSA id t2sm1251327lbr.45.2016.03.31.03.52.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 31 Mar 2016 03:52:30 -0700 (PDT) From: Vadim Yanitskiy To: openbsc@lists.osmocom.org Subject: [PATCH] db.c: implemented incremental migration Date: Thu, 31 Mar 2016 16:51:45 +0600 Message-Id: <1459421505-25727-1-git-send-email-axilirator@gmail.com> X-Mailer: git-send-email 2.8.0 X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Development of OpenBSC, OsmoBSC, OsmoNITB, OsmoCSCN" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vadim Yanitskiy Errors-To: openbsc-bounces@lists.osmocom.org Sender: "OpenBSC" 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 --- 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(-) diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c index 04aee79..ad5afca 100644 --- a/openbsc/src/libmsc/db.c +++ b/openbsc/src/libmsc/db.c @@ -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; } diff --git a/openbsc/tests/db/db_test.c b/openbsc/tests/db/db_test.c index a02d1f8..2fdd830 100644 --- a/openbsc/tests/db/db_test.c +++ b/openbsc/tests/db/db_test.c @@ -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); diff --git a/openbsc/tests/db/db_test.err b/openbsc/tests/db/db_test.err index fa9a54c..d8a3e7f 100644 --- a/openbsc/tests/db/db_test.err +++ b/openbsc/tests/db/db_test.err @@ -1,2 +1,5 @@ Going to migrate from revision 3 +Migration complete. +Going to migrate from revision 4 +Migration complete.  \ No newline at end of file