LCOV - code coverage report
Current view: top level - mlops-agent-1.8.8/daemon - service-db.cc (source / functions) Coverage Total Hit
Test: ML-Agent 1.8.8-0 platform/core/ml/mlops-agent#0e4faa58c1cc32b200623d31b6d332da9f779b87 Lines: 87.6 % 550 482
Test Date: 2026-04-30 21:36:08 Functions: 100.0 % 40 40

            Line data    Source code
       1              : /* SPDX-License-Identifier: Apache-2.0 */
       2              : /**
       3              :  * Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
       4              :  *
       5              :  * @file    service-db.cc
       6              :  * @date    29 Jul 2022
       7              :  * @brief   Database implementation of ML Agent
       8              :  * @see     https://github.com/nnstreamer/deviceMLOps.MLAgent
       9              :  * @author  Sangjung Woo <sangjung.woo@samsung.com>
      10              :  * @bug     No known bugs except for NYI items
      11              :  */
      12              : 
      13              : #include "service-db.hh"
      14              : #include "service-db-util.h"
      15              : #include "log.h"
      16              : 
      17              : #define sqlite3_clear_errmsg(m) \
      18              :   do {                          \
      19              :     if (m) {                    \
      20              :       sqlite3_free (m);         \
      21              :       (m) = nullptr;            \
      22              :     }                           \
      23              :   } while (0)
      24              : 
      25              : /**
      26              :  * @brief The version of pipeline table schema. It should be a positive integer.
      27              :  */
      28              : #define TBL_VER_PIPELINE_DESCRIPTION (1)
      29              : 
      30              : /**
      31              :  * @brief The version of model table schema. It should be a positive integer.
      32              :  */
      33              : #define TBL_VER_MODEL_INFO (1)
      34              : 
      35              : /**
      36              :  * @brief The version of resource table schema. It should be a positive integer.
      37              :  */
      38              : #define TBL_VER_RESOURCE_INFO (1)
      39              : 
      40              : typedef enum {
      41              :   TBL_DB_INFO = 0,
      42              :   TBL_PIPELINE_DESCRIPTION = 1,
      43              :   TBL_MODEL_INFO = 2,
      44              :   TBL_RESOURCE_INFO = 3,
      45              : 
      46              :   TBL_MAX
      47              : } mlsvc_table_e;
      48              : 
      49              : const char *g_mlsvc_table_schema_v1[] = {
      50              :   /* TBL_DB_INFO */ "tblMLDBInfo (name TEXT PRIMARY KEY NOT NULL, version INTEGER DEFAULT 1)",
      51              :   /* TBL_PIPELINE_DESCRIPTION */ "tblPipeline (key TEXT PRIMARY KEY NOT NULL, description TEXT, CHECK (length(description) > 0))",
      52              :   /* TBL_MODEL_INFO */ "tblModel (key TEXT NOT NULL, version INTEGER DEFAULT 1, active TEXT DEFAULT 'F', path TEXT, description TEXT, app_info TEXT, PRIMARY KEY (key, version), CHECK (length(path) > 0), CHECK (active IN ('T', 'F')))",
      53              :   /* TBL_RESOURCE_INFO */ "tblResource (key TEXT NOT NULL, path TEXT, description TEXT, app_info TEXT, PRIMARY KEY (key, path), CHECK (length(path) > 0))",
      54              :   /* Sentinel */ NULL
      55              : };
      56              : 
      57              : const char **g_mlsvc_table_schema = g_mlsvc_table_schema_v1;
      58              : 
      59              : /**
      60              :  * @brief Construct a new MLServiceDB object.
      61              :  * @param path database path
      62              :  */
      63           60 : MLServiceDB::MLServiceDB (std::string path)
      64           60 :     : _path (path), _initialized (false), _db (nullptr)
      65              : {
      66           60 : }
      67              : 
      68              : /**
      69              :  * @brief Destroy the MLServiceDB object.
      70              :  */
      71           92 : MLServiceDB::~MLServiceDB ()
      72              : {
      73           60 :   disconnectDB ();
      74           60 :   _initialized = false;
      75          124 : }
      76              : 
      77              : /**
      78              :  * @brief Create table and handle database version.
      79              :  */
      80              : void
      81           49 : MLServiceDB::initDB ()
      82              : {
      83              :   int i, tbl_ver;
      84              : 
      85           49 :   if (_initialized)
      86            0 :     return;
      87              : 
      88              :   /**
      89              :    * @todo data migration
      90              :    * handle database version and update each table
      91              :    * 1. get all records from table
      92              :    * 2. drop old table
      93              :    * 3. create new table and insert records
      94              :    */
      95           49 :   if (!set_transaction (true))
      96            0 :     return;
      97              : 
      98              :   /* Create tables. */
      99          245 :   for (i = 0; i < TBL_MAX; i++) {
     100          588 :     if (!create_table (g_mlsvc_table_schema[i]))
     101            0 :       return;
     102              :   }
     103              : 
     104              :   /* Check pipeline table. */
     105           98 :   if ((tbl_ver = get_table_version ("tblPipeline", TBL_VER_PIPELINE_DESCRIPTION)) < 0)
     106            0 :     return;
     107              : 
     108              :   if (tbl_ver != TBL_VER_PIPELINE_DESCRIPTION) {
     109              :     /** @todo update pipeline table if table schema is changed */
     110              :   }
     111              : 
     112           98 :   if (!set_table_version ("tblPipeline", TBL_VER_PIPELINE_DESCRIPTION))
     113            0 :     return;
     114              : 
     115              :   /* Check model table. */
     116           98 :   if ((tbl_ver = get_table_version ("tblModel", TBL_VER_MODEL_INFO)) < 0)
     117            0 :     return;
     118              : 
     119              :   if (tbl_ver != TBL_VER_MODEL_INFO) {
     120              :     /** @todo update model table if table schema is changed */
     121              :   }
     122              : 
     123           98 :   if (!set_table_version ("tblModel", TBL_VER_MODEL_INFO))
     124            0 :     return;
     125              : 
     126              :   /* Check resource table. */
     127           98 :   if ((tbl_ver = get_table_version ("tblResource", TBL_VER_RESOURCE_INFO)) < 0)
     128            0 :     return;
     129              : 
     130              :   if (tbl_ver != TBL_VER_RESOURCE_INFO) {
     131              :     /** @todo update resource table if table schema is changed */
     132              :   }
     133              : 
     134           98 :   if (!set_table_version ("tblResource", TBL_VER_RESOURCE_INFO))
     135            0 :     return;
     136              : 
     137           49 :   if (!set_transaction (false))
     138            0 :     return;
     139              : 
     140           49 :   _initialized = true;
     141              : }
     142              : 
     143              : /**
     144              :  * @brief Connect to ML Service DB and initialize the private variables.
     145              :  */
     146              : void
     147           49 : MLServiceDB::connectDB ()
     148              : {
     149              :   int rc;
     150              : 
     151           49 :   if (_db != nullptr)
     152            0 :     return;
     153              : 
     154           49 :   g_autofree gchar *db_path = g_strdup_printf ("%s/.ml-service.db", _path.c_str ());
     155           49 :   rc = sqlite3_open (db_path, &_db);
     156           49 :   if (rc != SQLITE_OK) {
     157            0 :     ml_loge ("Failed to open database: %s (ret: %d, path: %s)",
     158              :         sqlite3_errmsg (_db), rc, _path.c_str ());
     159            0 :     goto error;
     160              :   }
     161              : 
     162           49 :   initDB ();
     163              : 
     164           49 : error:
     165           49 :   if (!_initialized) {
     166            0 :     disconnectDB ();
     167            0 :     throw std::runtime_error ("Failed to connect DB.");
     168              :   }
     169           49 : }
     170              : 
     171              : /**
     172              :  * @brief Disconnect the DB.
     173              :  */
     174              : void
     175          109 : MLServiceDB::disconnectDB ()
     176              : {
     177          109 :   if (_db) {
     178           49 :     sqlite3_close (_db);
     179           49 :     _db = nullptr;
     180              :   }
     181          109 : }
     182              : 
     183              : /**
     184              :  * @brief Get table version.
     185              :  */
     186              : int
     187          147 : MLServiceDB::get_table_version (const std::string tbl_name, const int default_ver)
     188              : {
     189              :   int rc, tbl_ver;
     190              :   sqlite3_stmt *res;
     191          147 :   std::string sql = "SELECT version FROM tblMLDBInfo WHERE name = '" + tbl_name + "';";
     192              : 
     193          147 :   rc = sqlite3_prepare_v2 (_db, sql.c_str (), -1, &res, nullptr);
     194          147 :   if (rc != SQLITE_OK) {
     195            0 :     ml_logw ("Failed to get the version of table %s: %s (%d)",
     196              :         tbl_name.c_str (), sqlite3_errmsg (_db), rc);
     197            0 :     return -1;
     198              :   }
     199              : 
     200          147 :   tbl_ver = (sqlite3_step (res) == SQLITE_ROW) ? sqlite3_column_int (res, 0) : default_ver;
     201          147 :   sqlite3_finalize (res);
     202              : 
     203          147 :   return tbl_ver;
     204          147 : }
     205              : 
     206              : /**
     207              :  * @brief Set table version.
     208              :  */
     209              : bool
     210          147 : MLServiceDB::set_table_version (const std::string tbl_name, const int tbl_ver)
     211              : {
     212              :   sqlite3_stmt *res;
     213          147 :   std::string sql = "INSERT OR REPLACE INTO tblMLDBInfo VALUES (?1, ?2);";
     214              : 
     215          147 :   bool is_done = (sqlite3_prepare_v2 (_db, sql.c_str (), -1, &res, nullptr) == SQLITE_OK
     216          147 :                   && sqlite3_bind_text (res, 1, tbl_name.c_str (), -1, nullptr) == SQLITE_OK
     217          147 :                   && sqlite3_bind_int (res, 2, tbl_ver) == SQLITE_OK
     218          294 :                   && sqlite3_step (res) == SQLITE_DONE);
     219              : 
     220          147 :   sqlite3_finalize (res);
     221              : 
     222          147 :   if (!is_done)
     223            0 :     ml_logw ("Failed to update version of table %s.", tbl_name.c_str ());
     224          147 :   return is_done;
     225          147 : }
     226              : 
     227              : /**
     228              :  * @brief Create DB table.
     229              :  */
     230              : bool
     231          196 : MLServiceDB::create_table (const std::string tbl_name)
     232              : {
     233              :   int rc;
     234          196 :   char *errmsg = nullptr;
     235          196 :   std::string sql = "CREATE TABLE IF NOT EXISTS " + tbl_name;
     236              : 
     237          196 :   rc = sqlite3_exec (_db, sql.c_str (), nullptr, nullptr, &errmsg);
     238          196 :   if (rc != SQLITE_OK) {
     239            0 :     ml_logw ("Failed to create table %s: %s (%d)", tbl_name.c_str (), errmsg, rc);
     240            0 :     sqlite3_clear_errmsg (errmsg);
     241            0 :     return false;
     242              :   }
     243              : 
     244          196 :   return true;
     245          196 : }
     246              : 
     247              : /**
     248              :  * @brief Begin/end transaction.
     249              :  */
     250              : bool
     251          165 : MLServiceDB::set_transaction (bool begin)
     252              : {
     253              :   int rc;
     254          165 :   char *errmsg = nullptr;
     255              : 
     256          165 :   rc = sqlite3_exec (_db, begin ? "BEGIN TRANSACTION;" : "END TRANSACTION;",
     257              :       nullptr, nullptr, &errmsg);
     258          165 :   if (rc != SQLITE_OK)
     259            3 :     ml_logw ("Failed to %s transaction: %s (%d)", begin ? "begin" : "end", errmsg, rc);
     260              : 
     261          165 :   sqlite3_clear_errmsg (errmsg);
     262          165 :   return (rc == SQLITE_OK);
     263              : }
     264              : 
     265              : /**
     266              :  * @brief Set the pipeline description with the given name.
     267              :  * @note If the name already exists, the pipeline description is overwritten.
     268              :  * @param[in] name Unique name to set the associated pipeline description.
     269              :  * @param[in] description The pipeline description to be stored.
     270              :  */
     271              : void
     272            9 : MLServiceDB::set_pipeline (const std::string name, const std::string description)
     273              : {
     274              :   sqlite3_stmt *res;
     275              : 
     276            9 :   if (name.empty () || description.empty ())
     277            4 :     throw std::invalid_argument ("Invalid name or value parameters!");
     278              : 
     279            5 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_pipeline_");
     280            5 :   key_with_prefix += name;
     281              : 
     282            5 :   if (!set_transaction (true))
     283            1 :     throw std::runtime_error ("Failed to begin transaction.");
     284              : 
     285            4 :   if (sqlite3_prepare_v2 (_db,
     286              :           "INSERT OR REPLACE INTO tblPipeline VALUES (?1, ?2)", -1, &res, nullptr)
     287              :           != SQLITE_OK
     288            4 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     289            4 :       || sqlite3_bind_text (res, 2, description.c_str (), -1, nullptr) != SQLITE_OK
     290            8 :       || sqlite3_step (res) != SQLITE_DONE) {
     291            0 :     sqlite3_finalize (res);
     292            0 :     throw std::runtime_error ("Failed to insert pipeline description of " + name);
     293              :   }
     294              : 
     295            4 :   sqlite3_finalize (res);
     296              : 
     297            4 :   if (!set_transaction (false))
     298            0 :     throw std::runtime_error ("Failed to end transaction.");
     299            5 : }
     300              : 
     301              : /**
     302              :  * @brief Get the pipeline description with the given name.
     303              :  * @param[in] name The unique name to retrieve.
     304              :  * @param[out] description The pipeline corresponding with the given name.
     305              :  */
     306              : void
     307           10 : MLServiceDB::get_pipeline (const std::string name, gchar **description)
     308              : {
     309           10 :   char *value = nullptr;
     310              :   sqlite3_stmt *res;
     311              : 
     312           10 :   if (name.empty () || !description)
     313            4 :     throw std::invalid_argument ("Invalid name or description parameter!");
     314              : 
     315            6 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_pipeline_");
     316            6 :   key_with_prefix += name;
     317              : 
     318            6 :   if (sqlite3_prepare_v2 (_db,
     319              :           "SELECT description FROM tblPipeline WHERE key = ?1", -1, &res, nullptr)
     320              :           == SQLITE_OK
     321            5 :       && sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) == SQLITE_OK
     322           11 :       && sqlite3_step (res) == SQLITE_ROW)
     323            3 :     value = g_strdup_printf ("%s", sqlite3_column_text (res, 0));
     324              : 
     325            6 :   sqlite3_finalize (res);
     326              : 
     327            6 :   if (value) {
     328            3 :     *description = value;
     329              :   } else {
     330            3 :     throw std::invalid_argument ("Failed to get pipeline description of " + name);
     331              :   }
     332            6 : }
     333              : 
     334              : /**
     335              :  * @brief Delete the pipeline description with a given name.
     336              :  * @param[in] name The unique name to delete.
     337              :  */
     338              : void
     339            8 : MLServiceDB::delete_pipeline (const std::string name)
     340              : {
     341              :   sqlite3_stmt *res;
     342              : 
     343            8 :   if (name.empty ())
     344            2 :     throw std::invalid_argument ("Invalid name parameters!");
     345              : 
     346            6 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_pipeline_");
     347            6 :   key_with_prefix += name;
     348              : 
     349            6 :   if (sqlite3_prepare_v2 (_db, "DELETE FROM tblPipeline WHERE key = ?1", -1, &res, nullptr) != SQLITE_OK
     350            5 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     351           11 :       || sqlite3_step (res) != SQLITE_DONE) {
     352            1 :     sqlite3_finalize (res);
     353            1 :     throw std::runtime_error ("Failed to delete pipeline description of " + name);
     354              :   }
     355              : 
     356            5 :   sqlite3_finalize (res);
     357              : 
     358            5 :   if (sqlite3_changes (_db) == 0) {
     359            1 :     throw std::invalid_argument ("There is no pipeline description of " + name);
     360              :   }
     361            6 : }
     362              : 
     363              : /**
     364              :  * @brief Check the model is registered.
     365              :  */
     366              : bool
     367           40 : MLServiceDB::is_model_registered (const std::string key, const guint version)
     368              : {
     369              :   sqlite3_stmt *res;
     370              :   gchar *sql;
     371              :   bool registered;
     372              : 
     373           40 :   if (version > 0U)
     374           17 :     sql = g_strdup_printf (
     375              :         "SELECT EXISTS(SELECT 1 FROM tblModel WHERE key = ?1 AND version = %u)", version);
     376              :   else
     377           23 :     sql = g_strdup ("SELECT EXISTS(SELECT 1 FROM tblModel WHERE key = ?1)");
     378              : 
     379              :   registered
     380           78 :       = !(sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     381           38 :           || sqlite3_bind_text (res, 1, key.c_str (), -1, nullptr) != SQLITE_OK
     382           38 :           || sqlite3_step (res) != SQLITE_ROW || sqlite3_column_int (res, 0) != 1);
     383           40 :   sqlite3_finalize (res);
     384           40 :   g_free (sql);
     385              : 
     386           40 :   return registered;
     387              : }
     388              : 
     389              : /**
     390              :  * @brief Check the model is activated.
     391              :  */
     392              : bool
     393            1 : MLServiceDB::is_model_activated (const std::string key, const guint version)
     394              : {
     395              :   sqlite3_stmt *res;
     396              :   gchar *sql;
     397              :   bool activated;
     398              : 
     399            1 :   sql = g_strdup ("SELECT active FROM tblModel WHERE key = ?1 AND version = ?2");
     400              : 
     401            2 :   activated = !(sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     402            1 :                 || sqlite3_bind_text (res, 1, key.c_str (), -1, nullptr) != SQLITE_OK
     403            1 :                 || sqlite3_bind_int (res, 2, version) != SQLITE_OK
     404            1 :                 || sqlite3_step (res) != SQLITE_ROW
     405            1 :                 || !g_str_equal (sqlite3_column_text (res, 0), "T"));
     406            1 :   sqlite3_finalize (res);
     407            1 :   g_free (sql);
     408              : 
     409            1 :   return activated;
     410              : }
     411              : 
     412              : /**
     413              :  * @brief Check the resource is registered.
     414              :  */
     415              : bool
     416           16 : MLServiceDB::is_resource_registered (const std::string key)
     417              : {
     418              :   sqlite3_stmt *res;
     419              :   gchar *sql;
     420              :   bool registered;
     421              : 
     422           16 :   sql = g_strdup_printf ("SELECT EXISTS(SELECT 1 FROM tblResource WHERE key = ?1)");
     423              : 
     424              :   registered
     425           30 :       = !(sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     426           14 :           || sqlite3_bind_text (res, 1, key.c_str (), -1, nullptr) != SQLITE_OK
     427           14 :           || sqlite3_step (res) != SQLITE_ROW || sqlite3_column_int (res, 0) != 1);
     428           16 :   sqlite3_finalize (res);
     429           16 :   g_free (sql);
     430              : 
     431           16 :   return registered;
     432              : }
     433              : 
     434              : /**
     435              :  * @brief Set the model with the given name.
     436              :  * @param[in] name Unique name for model.
     437              :  * @param[in] model The model to be stored.
     438              :  * @param[in] is_active The model is active or not.
     439              :  * @param[in] description The model description.
     440              :  * @param[in] app_info The application information.
     441              :  * @param[out] version The version of the model.
     442              :  */
     443              : void
     444           20 : MLServiceDB::set_model (const std::string name, const std::string model, const bool is_active,
     445              :     const std::string description, const std::string app_info, guint *version)
     446              : {
     447           20 :   guint _version = 0U;
     448              :   sqlite3_stmt *res;
     449              : 
     450           20 :   if (name.empty () || model.empty () || !version)
     451            6 :     throw std::invalid_argument ("Invalid name, model, or version parameter!");
     452              : 
     453           14 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     454           14 :   key_with_prefix += name;
     455              : 
     456           14 :   if (!set_transaction (true))
     457            1 :     throw std::runtime_error ("Failed to begin transaction.");
     458              : 
     459              :   /* set other models as NOT active */
     460           13 :   if (is_active) {
     461            6 :     if (sqlite3_prepare_v2 (_db,
     462              :             "UPDATE tblModel SET active = 'F' WHERE key = ?1", -1, &res, nullptr)
     463              :             != SQLITE_OK
     464            6 :         || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     465           12 :         || sqlite3_step (res) != SQLITE_DONE) {
     466            0 :       sqlite3_finalize (res);
     467            0 :       throw std::runtime_error ("Failed to set other models as NOT active.");
     468              :     }
     469            6 :     sqlite3_finalize (res);
     470              :   }
     471              : 
     472              :   /* insert new row */
     473           13 :   if (sqlite3_prepare_v2 (_db, "INSERT OR REPLACE INTO tblModel VALUES (?1, IFNULL ((SELECT version from tblModel WHERE key = ?2 ORDER BY version DESC LIMIT 1) + 1, 1), ?3, ?4, ?5, ?6)",
     474              :           -1, &res, nullptr)
     475              :           != SQLITE_OK
     476           13 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     477           13 :       || sqlite3_bind_text (res, 2, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     478           13 :       || sqlite3_bind_text (res, 3, is_active ? "T" : "F", -1, nullptr) != SQLITE_OK
     479           13 :       || sqlite3_bind_text (res, 4, model.c_str (), -1, nullptr) != SQLITE_OK
     480           13 :       || sqlite3_bind_text (res, 5, description.c_str (), -1, nullptr) != SQLITE_OK
     481           13 :       || sqlite3_bind_text (res, 6, app_info.c_str (), -1, nullptr) != SQLITE_OK
     482           26 :       || sqlite3_step (res) != SQLITE_DONE) {
     483            0 :     sqlite3_finalize (res);
     484            0 :     throw std::runtime_error ("Failed to register the model " + name);
     485              :   }
     486              : 
     487           13 :   sqlite3_finalize (res);
     488              : 
     489           13 :   long long int last_id = sqlite3_last_insert_rowid (_db);
     490           13 :   if (last_id == 0) {
     491            0 :     ml_loge ("Failed to get last inserted row id: %s", sqlite3_errmsg (_db));
     492            0 :     throw std::runtime_error ("Failed to get last inserted row id.");
     493              :   }
     494              : 
     495              :   /* get model's version */
     496           13 :   if (sqlite3_prepare_v2 (_db, "SELECT version FROM tblModel WHERE rowid = ? ORDER BY version DESC LIMIT 1;",
     497              :           -1, &res, nullptr)
     498              :           == SQLITE_OK
     499           13 :       && sqlite3_bind_int (res, 1, last_id) == SQLITE_OK && sqlite3_step (res) == SQLITE_ROW) {
     500           13 :     _version = sqlite3_column_int (res, 0);
     501              :   }
     502              : 
     503           13 :   sqlite3_finalize (res);
     504              : 
     505           13 :   if (!set_transaction (false))
     506            0 :     throw std::runtime_error ("Failed to end transaction.");
     507              : 
     508           13 :   if (_version == 0) {
     509            0 :     ml_loge ("Failed to get model version with name %s: %s", name.c_str (),
     510              :         sqlite3_errmsg (_db));
     511            0 :     throw std::invalid_argument ("Failed to get model version of " + name);
     512              :   }
     513              : 
     514           13 :   *version = _version;
     515           14 : }
     516              : 
     517              : /**
     518              :  * @brief Update the model description with the given name.
     519              :  * @param[in] name Unique name for model.
     520              :  * @param[in] version The version of the model.
     521              :  * @param[in] description The model description.
     522              :  */
     523              : void
     524           11 : MLServiceDB::update_model_description (
     525              :     const std::string name, const guint version, const std::string description)
     526              : {
     527              :   sqlite3_stmt *res;
     528              : 
     529           11 :   if (name.empty () || description.empty ())
     530            4 :     throw std::invalid_argument ("Invalid name or description parameter!");
     531              : 
     532            7 :   if (version == 0U)
     533            3 :     throw std::invalid_argument ("Invalid version number!");
     534              : 
     535            4 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     536            4 :   key_with_prefix += name;
     537              : 
     538              :   /* check the existence of given model */
     539            4 :   if (!is_model_registered (key_with_prefix, version)) {
     540            2 :     throw std::invalid_argument ("Failed to check the existence of " + name
     541            4 :                                  + " version " + std::to_string (version));
     542              :   }
     543              : 
     544            2 :   if (!set_transaction (true))
     545            0 :     throw std::runtime_error ("Failed to begin transaction.");
     546              : 
     547              :   /* update model description */
     548            2 :   if (sqlite3_prepare_v2 (_db, "UPDATE tblModel SET description = ?1 WHERE key = ?2 AND version = ?3",
     549              :           -1, &res, nullptr)
     550              :           != SQLITE_OK
     551            2 :       || sqlite3_bind_text (res, 1, description.c_str (), -1, nullptr) != SQLITE_OK
     552            2 :       || sqlite3_bind_text (res, 2, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     553            4 :       || sqlite3_bind_int (res, 3, version) != SQLITE_OK || sqlite3_step (res) != SQLITE_DONE) {
     554            0 :     sqlite3_finalize (res);
     555            0 :     throw std::runtime_error ("Failed to update model description.");
     556              :   }
     557              : 
     558            2 :   sqlite3_finalize (res);
     559              : 
     560            2 :   if (!set_transaction (false))
     561            0 :     throw std::runtime_error ("Failed to end transaction.");
     562            4 : }
     563              : 
     564              : /**
     565              :  * @brief Activate the model with the given name.
     566              :  * @param[in] name Unique name for model.
     567              :  * @param[in] version The version of the model.
     568              :  */
     569              : void
     570            9 : MLServiceDB::activate_model (const std::string name, const guint version)
     571              : {
     572              :   sqlite3_stmt *res;
     573              : 
     574            9 :   if (name.empty ())
     575            2 :     throw std::invalid_argument ("Invalid name parameter!");
     576              : 
     577            7 :   if (version == 0U)
     578            3 :     throw std::invalid_argument ("Invalid version number!");
     579              : 
     580            4 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     581            4 :   key_with_prefix += name;
     582              : 
     583              :   /* check the existence */
     584            4 :   if (!is_model_registered (key_with_prefix, version)) {
     585            2 :     throw std::invalid_argument ("There is no model with name " + name
     586            4 :                                  + " and version " + std::to_string (version));
     587              :   }
     588              : 
     589            2 :   if (!set_transaction (true))
     590            0 :     throw std::runtime_error ("Failed to begin transaction.");
     591              : 
     592              :   /* set other row active as F */
     593            2 :   if (sqlite3_prepare_v2 (_db, "UPDATE tblModel SET active = 'F' WHERE key = ?1", -1, &res, nullptr) != SQLITE_OK
     594            2 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     595            4 :       || sqlite3_step (res) != SQLITE_DONE) {
     596            0 :     sqlite3_finalize (res);
     597            0 :     throw std::runtime_error ("Failed to deactivate other models of " + name);
     598              :   }
     599              : 
     600            2 :   sqlite3_finalize (res);
     601              : 
     602              :   /* set the given row active as T */
     603            2 :   if (sqlite3_prepare_v2 (_db, "UPDATE tblModel SET active = 'T' WHERE key = ?1 AND version = ?2",
     604              :           -1, &res, nullptr)
     605              :           != SQLITE_OK
     606            2 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     607            4 :       || sqlite3_bind_int (res, 2, version) != SQLITE_OK || sqlite3_step (res) != SQLITE_DONE) {
     608            0 :     sqlite3_finalize (res);
     609            0 :     throw std::runtime_error ("Failed to activate model with name " + name
     610            0 :                               + " and version " + std::to_string (version));
     611              :   }
     612              : 
     613            2 :   sqlite3_finalize (res);
     614              : 
     615            2 :   if (!set_transaction (false))
     616            0 :     throw std::runtime_error ("Failed to end transaction.");
     617            4 : }
     618              : 
     619              : /**
     620              :  * @brief Get the model with the given name.
     621              :  * @param[in] name The unique name to retrieve.
     622              :  * @param[in] version The version of the model. If it is 0, all models will return, if it is -1, return the active model.
     623              :  * @param[out] model The model corresponding with the given name.
     624              :  */
     625              : void
     626           24 : MLServiceDB::get_model (const std::string name, const gint version, gchar **model)
     627              : {
     628           24 :   const char model_info_json[]
     629              :       = "json_object('version', CAST(version AS TEXT), 'active', active, 'path', path, 'description', description, 'app_info', app_info)";
     630              :   char *sql;
     631           24 :   char *value = nullptr;
     632              :   sqlite3_stmt *res;
     633              : 
     634           24 :   if (name.empty () || !model)
     635            8 :     throw std::invalid_argument ("Invalid name or model parameters!");
     636              : 
     637           16 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     638           16 :   key_with_prefix += name;
     639              : 
     640              :   /* check the existence of given model */
     641           16 :   guint ver = (version > 0) ? version : 0U;
     642           16 :   if (!is_model_registered (key_with_prefix, ver)) {
     643            6 :     throw std::invalid_argument ("Failed to check the existence of " + name);
     644              :   }
     645              : 
     646           10 :   if (version == 0)
     647            4 :     sql = g_strdup_printf (
     648              :         "SELECT json_group_array(%s) FROM tblModel WHERE key = ?1", model_info_json);
     649            6 :   else if (version == -1)
     650            4 :     sql = g_strdup_printf ("SELECT %s FROM tblModel WHERE key = ?1 and active = 'T' ORDER BY version DESC LIMIT 1",
     651              :         model_info_json);
     652            2 :   else if (version > 0)
     653            2 :     sql = g_strdup_printf ("SELECT %s FROM tblModel WHERE key = ?1 and version = %d",
     654              :         model_info_json, version);
     655              :   else
     656            0 :     throw std::invalid_argument ("Invalid version parameter!");
     657              : 
     658           10 :   if (sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) == SQLITE_OK
     659           10 :       && sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) == SQLITE_OK
     660           20 :       && sqlite3_step (res) == SQLITE_ROW)
     661            9 :     value = g_strdup_printf ("%s", sqlite3_column_text (res, 0));
     662              : 
     663           10 :   sqlite3_finalize (res);
     664           10 :   g_free (sql);
     665              : 
     666           10 :   if (value) {
     667            9 :     *model = value;
     668              :   } else {
     669            1 :     throw std::invalid_argument ("Failed to get model with name " + name
     670            2 :                                  + " and version " + std::to_string (version));
     671              :   }
     672           16 : }
     673              : 
     674              : /**
     675              :  * @brief Delete the model.
     676              :  * @param[in] name The unique name to delete.
     677              :  * @param[in] version The version of the model to delete.
     678              :  * @param[in] force The model to delete by force (default is false).
     679              :  */
     680              : void
     681           18 : MLServiceDB::delete_model (const std::string name, const guint version, const gboolean force)
     682              : {
     683              :   char *sql;
     684              :   sqlite3_stmt *res;
     685              : 
     686           18 :   if (name.empty ())
     687            2 :     throw std::invalid_argument ("Invalid name parameters!");
     688              : 
     689           16 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     690           16 :   key_with_prefix += name;
     691              : 
     692              :   /* existence check */
     693           16 :   if (!is_model_registered (key_with_prefix, version)) {
     694            4 :     throw std::invalid_argument ("There is no model with name " + name
     695            8 :                                  + " and version " + std::to_string (version));
     696              :   }
     697              : 
     698           12 :   if (version > 0U) {
     699            3 :     if (force)
     700            2 :       ml_logw ("The model with name %s and version %u may be activated, delete it from ml-service.",
     701              :           name.c_str (), version);
     702            1 :     else if (is_model_activated (key_with_prefix, version))
     703            1 :       throw std::invalid_argument ("The model with name " + name
     704            2 :                                    + " and version " + std::to_string (version)
     705            3 :                                    + " is activated, cannot delete it.");
     706              : 
     707            2 :     sql = g_strdup_printf ("DELETE FROM tblModel WHERE key = ?1 and version = %u", version);
     708              :   } else {
     709            9 :     sql = g_strdup ("DELETE FROM tblModel WHERE key = ?1");
     710              :   }
     711              : 
     712           11 :   if (sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     713           11 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     714           22 :       || sqlite3_step (res) != SQLITE_DONE) {
     715            0 :     sqlite3_finalize (res);
     716            0 :     g_free (sql);
     717            0 :     throw std::runtime_error ("Failed to delete model with name " + name
     718            0 :                               + " and version " + std::to_string (version));
     719              :   }
     720              : 
     721           11 :   sqlite3_finalize (res);
     722           11 :   g_free (sql);
     723              : 
     724           11 :   if (sqlite3_changes (_db) == 0) {
     725            0 :     throw std::invalid_argument ("There is no model with the given name " + name
     726            0 :                                  + " and version " + std::to_string (version));
     727              :   }
     728           16 : }
     729              : 
     730              : /**
     731              :  * @brief Set the resource with given name.
     732              :  * @param[in] name Unique name of ml-resource.
     733              :  * @param[in] path The path to be stored.
     734              :  * @param[in] description The description for ml-resource.
     735              :  * @param[in] app_info The application information.
     736              :  */
     737              : void
     738           16 : MLServiceDB::set_resource (const std::string name, const std::string path,
     739              :     const std::string description, const std::string app_info)
     740              : {
     741              :   sqlite3_stmt *res;
     742              : 
     743           16 :   if (name.empty () || path.empty ())
     744            4 :     throw std::invalid_argument ("Invalid name or path parameter!");
     745              : 
     746           12 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_resource_");
     747           12 :   key_with_prefix += name;
     748              : 
     749           12 :   if (!set_transaction (true))
     750            1 :     throw std::runtime_error ("Failed to begin transaction.");
     751              : 
     752           11 :   if (sqlite3_prepare_v2 (_db,
     753              :           "INSERT OR REPLACE INTO tblResource VALUES (?1, ?2, ?3, ?4)", -1, &res, nullptr)
     754              :           != SQLITE_OK
     755           11 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     756           11 :       || sqlite3_bind_text (res, 2, path.c_str (), -1, nullptr) != SQLITE_OK
     757           11 :       || sqlite3_bind_text (res, 3, description.c_str (), -1, nullptr) != SQLITE_OK
     758           11 :       || sqlite3_bind_text (res, 4, app_info.c_str (), -1, nullptr) != SQLITE_OK
     759           22 :       || sqlite3_step (res) != SQLITE_DONE) {
     760            0 :     sqlite3_finalize (res);
     761            0 :     throw std::runtime_error ("Failed to add the resource " + name);
     762              :   }
     763              : 
     764           11 :   sqlite3_finalize (res);
     765              : 
     766           11 :   if (!set_transaction (false))
     767            0 :     throw std::runtime_error ("Failed to end transaction.");
     768              : 
     769           11 :   long long int last_id = sqlite3_last_insert_rowid (_db);
     770           11 :   if (last_id == 0) {
     771            0 :     ml_loge ("Failed to get last inserted row id: %s", sqlite3_errmsg (_db));
     772            0 :     throw std::runtime_error ("Failed to get last inserted row id.");
     773              :   }
     774           12 : }
     775              : 
     776              : /**
     777              :  * @brief Get the resource with given name.
     778              :  * @param[in] name The unique name to retrieve.
     779              :  * @param[out] resource The resource corresponding with the given name.
     780              :  */
     781              : void
     782           11 : MLServiceDB::get_resource (const std::string name, gchar **resource)
     783              : {
     784           11 :   const char res_info_json[]
     785              :       = "json_object('path', path, 'description', description, 'app_info', app_info)";
     786              :   char *sql;
     787           11 :   char *value = nullptr;
     788              :   sqlite3_stmt *res;
     789              : 
     790           11 :   if (name.empty () || !resource)
     791            4 :     throw std::invalid_argument ("Invalid name or resource parameters!");
     792              : 
     793            7 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_resource_");
     794            7 :   key_with_prefix += name;
     795              : 
     796              :   /* existence check */
     797            7 :   if (!is_resource_registered (key_with_prefix))
     798            3 :     throw std::invalid_argument ("There is no resource with name " + name);
     799              : 
     800              :   /* Get json string with insertion order. */
     801            4 :   sql = g_strdup_printf ("SELECT json_group_array(%s) FROM (SELECT * FROM tblResource WHERE key = ?1 ORDER BY ROWID ASC)",
     802              :       res_info_json);
     803              : 
     804            4 :   if (sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) == SQLITE_OK
     805            4 :       && sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) == SQLITE_OK
     806            8 :       && sqlite3_step (res) == SQLITE_ROW)
     807            4 :     value = g_strdup_printf ("%s", sqlite3_column_text (res, 0));
     808              : 
     809            4 :   sqlite3_finalize (res);
     810            4 :   g_free (sql);
     811              : 
     812            4 :   if (!value)
     813            0 :     throw std::invalid_argument ("Failed to get resource with name " + name);
     814              : 
     815            4 :   *resource = value;
     816            7 : }
     817              : 
     818              : /**
     819              :  * @brief Delete the resource.
     820              :  * @param[in] name The unique name to delete.
     821              :  */
     822              : void
     823           11 : MLServiceDB::delete_resource (const std::string name)
     824              : {
     825              :   char *sql;
     826              :   sqlite3_stmt *res;
     827              : 
     828           11 :   if (name.empty ())
     829            2 :     throw std::invalid_argument ("Invalid name parameters!");
     830              : 
     831            9 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_resource_");
     832            9 :   key_with_prefix += name;
     833              : 
     834              :   /* existence check */
     835            9 :   if (!is_resource_registered (key_with_prefix))
     836            3 :     throw std::invalid_argument ("There is no resource with name " + name);
     837              : 
     838            6 :   sql = g_strdup ("DELETE FROM tblResource WHERE key = ?1");
     839              : 
     840            6 :   if (sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     841            6 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     842           12 :       || sqlite3_step (res) != SQLITE_DONE) {
     843            0 :     sqlite3_finalize (res);
     844            0 :     g_free (sql);
     845            0 :     throw std::runtime_error ("Failed to delete resource with name " + name);
     846              :   }
     847              : 
     848            6 :   sqlite3_finalize (res);
     849            6 :   g_free (sql);
     850              : 
     851            6 :   if (sqlite3_changes (_db) == 0)
     852            0 :     throw std::invalid_argument ("There is no resource with name " + name);
     853            9 : }
     854              : 
     855              : static MLServiceDB *g_svcdb_instance = nullptr;
     856              : 
     857              : /**
     858              :  * @brief Get the service-db instance.
     859              :  */
     860              : static MLServiceDB *
     861          104 : svcdb_get (void)
     862              : {
     863          104 :   g_assert (g_svcdb_instance);
     864          104 :   return g_svcdb_instance;
     865              : }
     866              : 
     867              : G_BEGIN_DECLS
     868              : /**
     869              :  * @brief Initialize the service-db.
     870              :  */
     871              : gint
     872           32 : svcdb_initialize (const gchar *path)
     873              : {
     874           32 :   gint ret = 0;
     875              : 
     876           32 :   if (g_svcdb_instance) {
     877            0 :     ml_logw ("ML service DB is already opened, close old DB.");
     878            0 :     svcdb_finalize ();
     879              :   }
     880              : 
     881              :   try {
     882           64 :     g_svcdb_instance = new MLServiceDB (path);
     883           32 :     g_svcdb_instance->connectDB ();
     884            0 :   } catch (const std::exception &e) {
     885            0 :     ml_loge ("Failed to initialize database: %s", e.what ());
     886            0 :     svcdb_finalize ();
     887            0 :     ret = -EIO;
     888            0 :   }
     889              : 
     890           32 :   return ret;
     891              : }
     892              : 
     893              : /**
     894              :  * @brief Close the service-db.
     895              :  */
     896              : void
     897           32 : svcdb_finalize (void)
     898              : {
     899           32 :   if (g_svcdb_instance) {
     900           32 :     g_svcdb_instance->disconnectDB ();
     901           32 :     delete g_svcdb_instance;
     902              :   }
     903              : 
     904           32 :   g_svcdb_instance = nullptr;
     905           32 : }
     906              : 
     907              : /**
     908              :  * @brief Set the pipeline description with given name.
     909              :  * @note If the name already exists, the pipeline description is overwritten.
     910              :  * @param[in] name Unique name to set the associated pipeline description.
     911              :  * @param[in] description The pipeline description to be stored.
     912              :  * @return @c 0 on success. Otherwise a negative error value.
     913              :  */
     914              : gint
     915            8 : svcdb_pipeline_set (const gchar *name, const gchar *description)
     916              : {
     917            8 :   gint ret = 0;
     918            8 :   MLServiceDB *db = svcdb_get ();
     919              : 
     920              :   try {
     921           38 :     db->set_pipeline (name, description);
     922            4 :   } catch (const std::invalid_argument &e) {
     923            2 :     ml_loge ("%s", e.what ());
     924            2 :     ret = -EINVAL;
     925            4 :   } catch (const std::exception &e) {
     926            2 :     ml_loge ("%s", e.what ());
     927            2 :     ret = -EIO;
     928            2 :   }
     929              : 
     930            8 :   return ret;
     931              : }
     932              : 
     933              : /**
     934              :  * @brief Get the pipeline description with given name.
     935              :  * @param[in] name The unique name to retrieve.
     936              :  * @param[out] description The pipeline corresponding with given name.
     937              :  * @return @c 0 on success. Otherwise a negative error value.
     938              :  */
     939              : gint
     940            8 : svcdb_pipeline_get (const gchar *name, gchar **description)
     941              : {
     942            8 :   gint ret = 0;
     943            8 :   MLServiceDB *db = svcdb_get ();
     944              : 
     945              :   try {
     946           24 :     db->get_pipeline (name, description);
     947            5 :   } catch (const std::invalid_argument &e) {
     948            4 :     ml_loge ("%s", e.what ());
     949            4 :     ret = -EINVAL;
     950            5 :   } catch (const std::exception &e) {
     951            1 :     ml_loge ("%s", e.what ());
     952            1 :     ret = -EIO;
     953            1 :   }
     954              : 
     955            8 :   return ret;
     956              : }
     957              : 
     958              : /**
     959              :  * @brief Delete the pipeline description with a given name.
     960              :  * @param[in] name The unique name to delete.
     961              :  * @return @c 0 on success. Otherwise a negative error value.
     962              :  */
     963              : gint
     964            7 : svcdb_pipeline_delete (const gchar *name)
     965              : {
     966            7 :   gint ret = 0;
     967            7 :   MLServiceDB *db = svcdb_get ();
     968              : 
     969              :   try {
     970           21 :     db->delete_pipeline (name);
     971            3 :   } catch (const std::invalid_argument &e) {
     972            2 :     ml_loge ("%s", e.what ());
     973            2 :     ret = -EINVAL;
     974            3 :   } catch (const std::exception &e) {
     975            1 :     ml_loge ("%s", e.what ());
     976            1 :     ret = -EIO;
     977            1 :   }
     978              : 
     979            7 :   return ret;
     980              : }
     981              : 
     982              : /**
     983              :  * @brief Add the model with given name.
     984              :  * @param[in] name Unique name for model.
     985              :  * @param[in] model The model to be stored.
     986              :  * @param[in] is_active The model is active or not.
     987              :  * @param[in] description The model description.
     988              :  * @param[in] app_info The application information.
     989              :  * @param[out] version The version of the model.
     990              :  * @return @c 0 on success. Otherwise a negative error value.
     991              :  */
     992              : gint
     993           14 : svcdb_model_add (const gchar *name, const gchar *path, const bool is_active,
     994              :     const gchar *description, const gchar *app_info, guint *version)
     995              : {
     996           14 :   gint ret = 0;
     997           14 :   MLServiceDB *db = svcdb_get ();
     998              : 
     999              :   try {
    1000          116 :     db->set_model (name, path, is_active, description, app_info, version);
    1001            5 :   } catch (const std::invalid_argument &e) {
    1002            3 :     ml_loge ("%s", e.what ());
    1003            3 :     ret = -EINVAL;
    1004            5 :   } catch (const std::exception &e) {
    1005            2 :     ml_loge ("%s", e.what ());
    1006            2 :     ret = -EIO;
    1007            2 :   }
    1008              : 
    1009           14 :   return ret;
    1010              : }
    1011              : 
    1012              : /**
    1013              :  * @brief Update the model description with given name and version.
    1014              :  * @param[in] name Unique name for model.
    1015              :  * @param[in] version The version of the model.
    1016              :  * @param[in] description The model description.
    1017              :  * @return @c 0 on success. Otherwise a negative error value.
    1018              :  */
    1019              : gint
    1020            8 : svcdb_model_update_description (const gchar *name, const guint version,
    1021              :     const gchar *description)
    1022              : {
    1023            8 :   gint ret = 0;
    1024            8 :   MLServiceDB *db = svcdb_get ();
    1025              : 
    1026              :   try {
    1027           38 :     db->update_model_description (name, version, description);
    1028            7 :   } catch (const std::invalid_argument &e) {
    1029            5 :     ml_loge ("%s", e.what ());
    1030            5 :     ret = -EINVAL;
    1031            7 :   } catch (const std::exception &e) {
    1032            2 :     ml_loge ("%s", e.what ());
    1033            2 :     ret = -EIO;
    1034            2 :   }
    1035              : 
    1036            8 :   return ret;
    1037              : }
    1038              : 
    1039              : /**
    1040              :  * @brief Activate the model with given name.
    1041              :  * @param[in] name Unique name for model.
    1042              :  * @param[in] version The version of the model.
    1043              :  * @return @c 0 on success. Otherwise a negative error value.
    1044              :  */
    1045              : gint
    1046            6 : svcdb_model_activate (const gchar *name, const guint version)
    1047              : {
    1048            6 :   gint ret = 0;
    1049            6 :   MLServiceDB *db = svcdb_get ();
    1050              : 
    1051              :   try {
    1052           18 :     db->activate_model (name, version);
    1053            5 :   } catch (const std::invalid_argument &e) {
    1054            4 :     ml_loge ("%s", e.what ());
    1055            4 :     ret = -EINVAL;
    1056            5 :   } catch (const std::exception &e) {
    1057            1 :     ml_loge ("%s", e.what ());
    1058            1 :     ret = -EIO;
    1059            1 :   }
    1060              : 
    1061            6 :   return ret;
    1062              : }
    1063              : 
    1064              : /**
    1065              :  * @brief Get the model information with given name and version.
    1066              :  * @param[in] name The unique name to retrieve.
    1067              :  * @param[in] version The version of the model. If it is 0, all models will return, if it is -1, return the active model.
    1068              :  * @param[out] model_info The model information.
    1069              :  * @return @c 0 on success. Otherwise a negative error value.
    1070              :  */
    1071              : gint
    1072            6 : svcdb_model_get (const gchar *name, const guint version, gchar **model_info)
    1073              : {
    1074            6 :   gint ret = 0;
    1075            6 :   MLServiceDB *db = svcdb_get ();
    1076              : 
    1077              :   try {
    1078           18 :     db->get_model (name, version, model_info);
    1079            5 :   } catch (const std::invalid_argument &e) {
    1080            4 :     ml_loge ("%s", e.what ());
    1081            4 :     ret = -EINVAL;
    1082            5 :   } catch (const std::exception &e) {
    1083            1 :     ml_loge ("%s", e.what ());
    1084            1 :     ret = -EIO;
    1085            1 :   }
    1086              : 
    1087            6 :   return ret;
    1088              : }
    1089              : 
    1090              : /**
    1091              :  * @brief Get the activated model information with given name.
    1092              :  * @param[in] name The unique name to retrieve.
    1093              :  * @param[out] model_info The model information.
    1094              :  * @return @c 0 on success. Otherwise a negative error value.
    1095              :  */
    1096              : gint
    1097            6 : svcdb_model_get_activated (const gchar *name, gchar **model_info)
    1098              : {
    1099            6 :   gint ret = 0;
    1100            6 :   MLServiceDB *db = svcdb_get ();
    1101              : 
    1102              :   try {
    1103           18 :     db->get_model (name, -1, model_info);
    1104            5 :   } catch (const std::invalid_argument &e) {
    1105            4 :     ml_loge ("%s", e.what ());
    1106            4 :     ret = -EINVAL;
    1107            5 :   } catch (const std::exception &e) {
    1108            1 :     ml_loge ("%s", e.what ());
    1109            1 :     ret = -EIO;
    1110            1 :   }
    1111              : 
    1112            6 :   return ret;
    1113              : }
    1114              : 
    1115              : /**
    1116              :  * @brief Get the model information with given name.
    1117              :  * @param[in] name The unique name to retrieve.
    1118              :  * @param[out] model_info The model information.
    1119              :  * @return @c 0 on success. Otherwise a negative error value.
    1120              :  */
    1121              : gint
    1122            7 : svcdb_model_get_all (const gchar *name, gchar **model_info)
    1123              : {
    1124            7 :   gint ret = 0;
    1125            7 :   MLServiceDB *db = svcdb_get ();
    1126              : 
    1127              :   try {
    1128           21 :     db->get_model (name, 0, model_info);
    1129            4 :   } catch (const std::invalid_argument &e) {
    1130            3 :     ml_loge ("%s", e.what ());
    1131            3 :     ret = -EINVAL;
    1132            4 :   } catch (const std::exception &e) {
    1133            1 :     ml_loge ("%s", e.what ());
    1134            1 :     ret = -EIO;
    1135            1 :   }
    1136              : 
    1137            7 :   return ret;
    1138              : }
    1139              : 
    1140              : /**
    1141              :  * @brief Delete the model.
    1142              :  * @param[in] name The unique name to delete.
    1143              :  * @param[in] version The version of the model to delete.
    1144              :  * @param[in] force If the force is set to @c TRUE, the target model will be forced to delete.
    1145              :  * @return @c 0 on success. Otherwise a negative error value.
    1146              :  */
    1147              : gint
    1148           12 : svcdb_model_delete (const gchar *name, const guint version, const gboolean force)
    1149              : {
    1150           12 :   gint ret = 0;
    1151           12 :   MLServiceDB *db = svcdb_get ();
    1152              : 
    1153              :   try {
    1154           36 :     db->delete_model (name, version, force);
    1155            4 :   } catch (const std::invalid_argument &e) {
    1156            3 :     ml_loge ("%s", e.what ());
    1157            3 :     ret = -EINVAL;
    1158            4 :   } catch (const std::exception &e) {
    1159            1 :     ml_loge ("%s", e.what ());
    1160            1 :     ret = -EIO;
    1161            1 :   }
    1162              : 
    1163           12 :   return ret;
    1164              : }
    1165              : 
    1166              : /**
    1167              :  * @brief Set the resource with given name.
    1168              :  * @param[in] name Unique name of ml-resource.
    1169              :  * @param[in] path The path to be stored.
    1170              :  * @param[in] description The description for ml-resource.
    1171              :  * @param[in] app_info The application information.
    1172              :  * @return @c 0 on success. Otherwise a negative error value.
    1173              :  */
    1174              : gint
    1175           10 : svcdb_resource_add (const gchar *name, const gchar *path,
    1176              :     const gchar *description, const gchar *app_info)
    1177              : {
    1178           10 :   gint ret = 0;
    1179           10 :   MLServiceDB *db = svcdb_get ();
    1180              : 
    1181              :   try {
    1182           80 :     db->set_resource (name, path, description, app_info);
    1183            4 :   } catch (const std::invalid_argument &e) {
    1184            2 :     ml_loge ("%s", e.what ());
    1185            2 :     ret = -EINVAL;
    1186            4 :   } catch (const std::exception &e) {
    1187            2 :     ml_loge ("%s", e.what ());
    1188            2 :     ret = -EIO;
    1189            2 :   }
    1190              : 
    1191           10 :   return ret;
    1192              : }
    1193              : 
    1194              : /**
    1195              :  * @brief Get the resource with given name.
    1196              :  * @param[in] name The unique name to retrieve.
    1197              :  * @param[out] resource The resource information.
    1198              :  * @return @c 0 on success. Otherwise a negative error value.
    1199              :  */
    1200              : gint
    1201            6 : svcdb_resource_get (const gchar *name, gchar **res_info)
    1202              : {
    1203            6 :   gint ret = 0;
    1204            6 :   MLServiceDB *db = svcdb_get ();
    1205              : 
    1206              :   try {
    1207           18 :     db->get_resource (name, res_info);
    1208            4 :   } catch (const std::invalid_argument &e) {
    1209            3 :     ml_loge ("%s", e.what ());
    1210            3 :     ret = -EINVAL;
    1211            4 :   } catch (const std::exception &e) {
    1212            1 :     ml_loge ("%s", e.what ());
    1213            1 :     ret = -EIO;
    1214            1 :   }
    1215              : 
    1216            6 :   return ret;
    1217              : }
    1218              : 
    1219              : /**
    1220              :  * @brief Delete the resource.
    1221              :  * @param[in] name The unique name to delete.
    1222              :  * @return @c 0 on success. Otherwise a negative error value.
    1223              :  */
    1224              : gint
    1225            6 : svcdb_resource_delete (const gchar *name)
    1226              : {
    1227            6 :   gint ret = 0;
    1228            6 :   MLServiceDB *db = svcdb_get ();
    1229              : 
    1230              :   try {
    1231           18 :     db->delete_resource (name);
    1232            3 :   } catch (const std::invalid_argument &e) {
    1233            2 :     ml_loge ("%s", e.what ());
    1234            2 :     ret = -EINVAL;
    1235            3 :   } catch (const std::exception &e) {
    1236            1 :     ml_loge ("%s", e.what ());
    1237            1 :     ret = -EIO;
    1238            1 :   }
    1239              : 
    1240            6 :   return ret;
    1241              : }
    1242              : G_END_DECLS
        

Generated by: LCOV version 2.4-0