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#7b658b7dd8532af4825478883945a4c388cff1b4 Lines: 0.0 % 545 0
Test Date: 2026-05-07 08:04:31 Functions: 0.0 % 40 0

            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            0 : MLServiceDB::MLServiceDB (std::string path)
      64            0 :     : _path (path), _initialized (false), _db (nullptr)
      65              : {
      66            0 : }
      67              : 
      68              : /**
      69              :  * @brief Destroy the MLServiceDB object.
      70              :  */
      71            0 : MLServiceDB::~MLServiceDB ()
      72              : {
      73            0 :   disconnectDB ();
      74            0 :   _initialized = false;
      75            0 : }
      76              : 
      77              : /**
      78              :  * @brief Create table and handle database version.
      79              :  */
      80              : void
      81            0 : MLServiceDB::initDB ()
      82              : {
      83              :   int i, tbl_ver;
      84              : 
      85            0 :   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            0 :   if (!set_transaction (true))
      96            0 :     return;
      97              : 
      98              :   /* Create tables. */
      99            0 :   for (i = 0; i < TBL_MAX; i++) {
     100            0 :     if (!create_table (g_mlsvc_table_schema[i]))
     101            0 :       return;
     102              :   }
     103              : 
     104              :   /* Check pipeline table. */
     105            0 :   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            0 :   if (!set_table_version ("tblPipeline", TBL_VER_PIPELINE_DESCRIPTION))
     113            0 :     return;
     114              : 
     115              :   /* Check model table. */
     116            0 :   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            0 :   if (!set_table_version ("tblModel", TBL_VER_MODEL_INFO))
     124            0 :     return;
     125              : 
     126              :   /* Check resource table. */
     127            0 :   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            0 :   if (!set_table_version ("tblResource", TBL_VER_RESOURCE_INFO))
     135            0 :     return;
     136              : 
     137            0 :   if (!set_transaction (false))
     138            0 :     return;
     139              : 
     140            0 :   _initialized = true;
     141              : }
     142              : 
     143              : /**
     144              :  * @brief Connect to ML Service DB and initialize the private variables.
     145              :  */
     146              : void
     147            0 : MLServiceDB::connectDB ()
     148              : {
     149              :   int rc;
     150              : 
     151            0 :   if (_db != nullptr)
     152            0 :     return;
     153              : 
     154            0 :   g_autofree gchar *db_path = g_strdup_printf ("%s/.ml-service.db", _path.c_str ());
     155            0 :   rc = sqlite3_open (db_path, &_db);
     156            0 :   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            0 :   initDB ();
     163              : 
     164            0 : error:
     165            0 :   if (!_initialized) {
     166            0 :     disconnectDB ();
     167            0 :     throw std::runtime_error ("Failed to connect DB.");
     168              :   }
     169            0 : }
     170              : 
     171              : /**
     172              :  * @brief Disconnect the DB.
     173              :  */
     174              : void
     175            0 : MLServiceDB::disconnectDB ()
     176              : {
     177            0 :   if (_db) {
     178            0 :     sqlite3_close (_db);
     179            0 :     _db = nullptr;
     180              :   }
     181            0 : }
     182              : 
     183              : /**
     184              :  * @brief Get table version.
     185              :  */
     186              : int
     187            0 : MLServiceDB::get_table_version (const std::string tbl_name, const int default_ver)
     188              : {
     189              :   int rc, tbl_ver;
     190              :   sqlite3_stmt *res;
     191            0 :   std::string sql = "SELECT version FROM tblMLDBInfo WHERE name = '" + tbl_name + "';";
     192              : 
     193            0 :   rc = sqlite3_prepare_v2 (_db, sql.c_str (), -1, &res, nullptr);
     194            0 :   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            0 :   tbl_ver = (sqlite3_step (res) == SQLITE_ROW) ? sqlite3_column_int (res, 0) : default_ver;
     201            0 :   sqlite3_finalize (res);
     202              : 
     203            0 :   return tbl_ver;
     204            0 : }
     205              : 
     206              : /**
     207              :  * @brief Set table version.
     208              :  */
     209              : bool
     210            0 : MLServiceDB::set_table_version (const std::string tbl_name, const int tbl_ver)
     211              : {
     212              :   sqlite3_stmt *res;
     213            0 :   std::string sql = "INSERT OR REPLACE INTO tblMLDBInfo VALUES (?1, ?2);";
     214              : 
     215            0 :   bool is_done = (sqlite3_prepare_v2 (_db, sql.c_str (), -1, &res, nullptr) == SQLITE_OK
     216            0 :                   && sqlite3_bind_text (res, 1, tbl_name.c_str (), -1, nullptr) == SQLITE_OK
     217            0 :                   && sqlite3_bind_int (res, 2, tbl_ver) == SQLITE_OK
     218            0 :                   && sqlite3_step (res) == SQLITE_DONE);
     219              : 
     220            0 :   sqlite3_finalize (res);
     221              : 
     222            0 :   if (!is_done)
     223            0 :     ml_logw ("Failed to update version of table %s.", tbl_name.c_str ());
     224            0 :   return is_done;
     225            0 : }
     226              : 
     227              : /**
     228              :  * @brief Create DB table.
     229              :  */
     230              : bool
     231            0 : MLServiceDB::create_table (const std::string tbl_name)
     232              : {
     233              :   int rc;
     234            0 :   char *errmsg = nullptr;
     235            0 :   std::string sql = "CREATE TABLE IF NOT EXISTS " + tbl_name;
     236              : 
     237            0 :   rc = sqlite3_exec (_db, sql.c_str (), nullptr, nullptr, &errmsg);
     238            0 :   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            0 :   return true;
     245            0 : }
     246              : 
     247              : /**
     248              :  * @brief Begin/end transaction.
     249              :  */
     250              : bool
     251            0 : MLServiceDB::set_transaction (bool begin)
     252              : {
     253              :   int rc;
     254            0 :   char *errmsg = nullptr;
     255              : 
     256            0 :   rc = sqlite3_exec (_db, begin ? "BEGIN TRANSACTION;" : "END TRANSACTION;",
     257              :       nullptr, nullptr, &errmsg);
     258            0 :   if (rc != SQLITE_OK)
     259            0 :     ml_logw ("Failed to %s transaction: %s (%d)", begin ? "begin" : "end", errmsg, rc);
     260              : 
     261            0 :   sqlite3_clear_errmsg (errmsg);
     262            0 :   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            0 : MLServiceDB::set_pipeline (const std::string name, const std::string description)
     273              : {
     274              :   sqlite3_stmt *res;
     275              : 
     276            0 :   if (name.empty () || description.empty ())
     277            0 :     throw std::invalid_argument ("Invalid name or value parameters!");
     278              : 
     279            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_pipeline_");
     280            0 :   key_with_prefix += name;
     281              : 
     282            0 :   if (!set_transaction (true))
     283            0 :     throw std::runtime_error ("Failed to begin transaction.");
     284              : 
     285            0 :   if (sqlite3_prepare_v2 (_db,
     286              :           "INSERT OR REPLACE INTO tblPipeline VALUES (?1, ?2)", -1, &res, nullptr)
     287              :           != SQLITE_OK
     288            0 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     289            0 :       || sqlite3_bind_text (res, 2, description.c_str (), -1, nullptr) != SQLITE_OK
     290            0 :       || 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            0 :   sqlite3_finalize (res);
     296              : 
     297            0 :   if (!set_transaction (false))
     298            0 :     throw std::runtime_error ("Failed to end transaction.");
     299            0 : }
     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            0 : MLServiceDB::get_pipeline (const std::string name, gchar **description)
     308              : {
     309            0 :   char *value = nullptr;
     310              :   sqlite3_stmt *res;
     311              : 
     312            0 :   if (name.empty () || !description)
     313            0 :     throw std::invalid_argument ("Invalid name or description parameter!");
     314              : 
     315            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_pipeline_");
     316            0 :   key_with_prefix += name;
     317              : 
     318            0 :   if (sqlite3_prepare_v2 (_db,
     319              :           "SELECT description FROM tblPipeline WHERE key = ?1", -1, &res, nullptr)
     320              :           == SQLITE_OK
     321            0 :       && sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) == SQLITE_OK
     322            0 :       && sqlite3_step (res) == SQLITE_ROW)
     323            0 :     value = g_strdup_printf ("%s", sqlite3_column_text (res, 0));
     324              : 
     325            0 :   sqlite3_finalize (res);
     326              : 
     327            0 :   if (value) {
     328            0 :     *description = value;
     329              :   } else {
     330            0 :     throw std::invalid_argument ("Failed to get pipeline description of " + name);
     331              :   }
     332            0 : }
     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            0 : MLServiceDB::delete_pipeline (const std::string name)
     340              : {
     341              :   sqlite3_stmt *res;
     342              : 
     343            0 :   if (name.empty ())
     344            0 :     throw std::invalid_argument ("Invalid name parameters!");
     345              : 
     346            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_pipeline_");
     347            0 :   key_with_prefix += name;
     348              : 
     349            0 :   if (sqlite3_prepare_v2 (_db, "DELETE FROM tblPipeline WHERE key = ?1", -1, &res, nullptr) != SQLITE_OK
     350            0 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     351            0 :       || sqlite3_step (res) != SQLITE_DONE) {
     352            0 :     sqlite3_finalize (res);
     353            0 :     throw std::runtime_error ("Failed to delete pipeline description of " + name);
     354              :   }
     355              : 
     356            0 :   sqlite3_finalize (res);
     357              : 
     358            0 :   if (sqlite3_changes (_db) == 0) {
     359            0 :     throw std::invalid_argument ("There is no pipeline description of " + name);
     360              :   }
     361            0 : }
     362              : 
     363              : /**
     364              :  * @brief Check the model is registered.
     365              :  */
     366              : bool
     367            0 : MLServiceDB::is_model_registered (const std::string key, const guint version)
     368              : {
     369              :   sqlite3_stmt *res;
     370              :   gchar *sql;
     371              :   bool registered;
     372              : 
     373            0 :   if (version > 0U)
     374            0 :     sql = g_strdup_printf (
     375              :         "SELECT EXISTS(SELECT 1 FROM tblModel WHERE key = ?1 AND version = %u)", version);
     376              :   else
     377            0 :     sql = g_strdup ("SELECT EXISTS(SELECT 1 FROM tblModel WHERE key = ?1)");
     378              : 
     379              :   registered
     380            0 :       = !(sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     381            0 :           || sqlite3_bind_text (res, 1, key.c_str (), -1, nullptr) != SQLITE_OK
     382            0 :           || sqlite3_step (res) != SQLITE_ROW || sqlite3_column_int (res, 0) != 1);
     383            0 :   sqlite3_finalize (res);
     384            0 :   g_free (sql);
     385              : 
     386            0 :   return registered;
     387              : }
     388              : 
     389              : /**
     390              :  * @brief Check the model is activated.
     391              :  */
     392              : bool
     393            0 : MLServiceDB::is_model_activated (const std::string key, const guint version)
     394              : {
     395              :   sqlite3_stmt *res;
     396              :   gchar *sql;
     397              :   bool activated;
     398              : 
     399            0 :   sql = g_strdup ("SELECT active FROM tblModel WHERE key = ?1 AND version = ?2");
     400              : 
     401            0 :   activated = !(sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     402            0 :                 || sqlite3_bind_text (res, 1, key.c_str (), -1, nullptr) != SQLITE_OK
     403            0 :                 || sqlite3_bind_int (res, 2, version) != SQLITE_OK
     404            0 :                 || sqlite3_step (res) != SQLITE_ROW
     405            0 :                 || !g_str_equal (sqlite3_column_text (res, 0), "T"));
     406            0 :   sqlite3_finalize (res);
     407            0 :   g_free (sql);
     408              : 
     409            0 :   return activated;
     410              : }
     411              : 
     412              : /**
     413              :  * @brief Check the resource is registered.
     414              :  */
     415              : bool
     416            0 : MLServiceDB::is_resource_registered (const std::string key)
     417              : {
     418              :   sqlite3_stmt *res;
     419              :   gchar *sql;
     420              :   bool registered;
     421              : 
     422            0 :   sql = g_strdup_printf ("SELECT EXISTS(SELECT 1 FROM tblResource WHERE key = ?1)");
     423              : 
     424              :   registered
     425            0 :       = !(sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     426            0 :           || sqlite3_bind_text (res, 1, key.c_str (), -1, nullptr) != SQLITE_OK
     427            0 :           || sqlite3_step (res) != SQLITE_ROW || sqlite3_column_int (res, 0) != 1);
     428            0 :   sqlite3_finalize (res);
     429            0 :   g_free (sql);
     430              : 
     431            0 :   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            0 : 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            0 :   guint _version = 0U;
     448              :   sqlite3_stmt *res;
     449              : 
     450            0 :   if (name.empty () || model.empty () || !version)
     451            0 :     throw std::invalid_argument ("Invalid name, model, or version parameter!");
     452              : 
     453            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     454            0 :   key_with_prefix += name;
     455              : 
     456            0 :   if (!set_transaction (true))
     457            0 :     throw std::runtime_error ("Failed to begin transaction.");
     458              : 
     459              :   /* set other models as NOT active */
     460            0 :   if (is_active) {
     461            0 :     if (sqlite3_prepare_v2 (_db,
     462              :             "UPDATE tblModel SET active = 'F' WHERE key = ?1", -1, &res, nullptr)
     463              :             != SQLITE_OK
     464            0 :         || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     465            0 :         || 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            0 :     sqlite3_finalize (res);
     470              :   }
     471              : 
     472              :   /* insert new row */
     473            0 :   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            0 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     477            0 :       || sqlite3_bind_text (res, 2, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     478            0 :       || sqlite3_bind_text (res, 3, is_active ? "T" : "F", -1, nullptr) != SQLITE_OK
     479            0 :       || sqlite3_bind_text (res, 4, model.c_str (), -1, nullptr) != SQLITE_OK
     480            0 :       || sqlite3_bind_text (res, 5, description.c_str (), -1, nullptr) != SQLITE_OK
     481            0 :       || sqlite3_bind_text (res, 6, app_info.c_str (), -1, nullptr) != SQLITE_OK
     482            0 :       || 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            0 :   sqlite3_finalize (res);
     488              : 
     489            0 :   long long int last_id = sqlite3_last_insert_rowid (_db);
     490            0 :   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            0 :   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            0 :       && sqlite3_bind_int (res, 1, last_id) == SQLITE_OK && sqlite3_step (res) == SQLITE_ROW) {
     500            0 :     _version = sqlite3_column_int (res, 0);
     501              :   }
     502              : 
     503            0 :   sqlite3_finalize (res);
     504              : 
     505            0 :   if (!set_transaction (false))
     506            0 :     throw std::runtime_error ("Failed to end transaction.");
     507              : 
     508            0 :   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            0 :   *version = _version;
     515            0 : }
     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            0 : MLServiceDB::update_model_description (
     525              :     const std::string name, const guint version, const std::string description)
     526              : {
     527              :   sqlite3_stmt *res;
     528              : 
     529            0 :   if (name.empty () || description.empty ())
     530            0 :     throw std::invalid_argument ("Invalid name or description parameter!");
     531              : 
     532            0 :   if (version == 0U)
     533            0 :     throw std::invalid_argument ("Invalid version number!");
     534              : 
     535            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     536            0 :   key_with_prefix += name;
     537              : 
     538              :   /* check the existence of given model */
     539            0 :   if (!is_model_registered (key_with_prefix, version)) {
     540            0 :     throw std::invalid_argument ("Failed to check the existence of " + name
     541            0 :                                  + " version " + std::to_string (version));
     542              :   }
     543              : 
     544            0 :   if (!set_transaction (true))
     545            0 :     throw std::runtime_error ("Failed to begin transaction.");
     546              : 
     547              :   /* update model description */
     548            0 :   if (sqlite3_prepare_v2 (_db, "UPDATE tblModel SET description = ?1 WHERE key = ?2 AND version = ?3",
     549              :           -1, &res, nullptr)
     550              :           != SQLITE_OK
     551            0 :       || sqlite3_bind_text (res, 1, description.c_str (), -1, nullptr) != SQLITE_OK
     552            0 :       || sqlite3_bind_text (res, 2, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     553            0 :       || 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            0 :   sqlite3_finalize (res);
     559              : 
     560            0 :   if (!set_transaction (false))
     561            0 :     throw std::runtime_error ("Failed to end transaction.");
     562            0 : }
     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            0 : MLServiceDB::activate_model (const std::string name, const guint version)
     571              : {
     572              :   sqlite3_stmt *res;
     573              : 
     574            0 :   if (name.empty ())
     575            0 :     throw std::invalid_argument ("Invalid name parameter!");
     576              : 
     577            0 :   if (version == 0U)
     578            0 :     throw std::invalid_argument ("Invalid version number!");
     579              : 
     580            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     581            0 :   key_with_prefix += name;
     582              : 
     583              :   /* check the existence */
     584            0 :   if (!is_model_registered (key_with_prefix, version)) {
     585            0 :     throw std::invalid_argument ("There is no model with name " + name
     586            0 :                                  + " and version " + std::to_string (version));
     587              :   }
     588              : 
     589            0 :   if (!set_transaction (true))
     590            0 :     throw std::runtime_error ("Failed to begin transaction.");
     591              : 
     592              :   /* set other row active as F */
     593            0 :   if (sqlite3_prepare_v2 (_db, "UPDATE tblModel SET active = 'F' WHERE key = ?1", -1, &res, nullptr) != SQLITE_OK
     594            0 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     595            0 :       || 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            0 :   sqlite3_finalize (res);
     601              : 
     602              :   /* set the given row active as T */
     603            0 :   if (sqlite3_prepare_v2 (_db, "UPDATE tblModel SET active = 'T' WHERE key = ?1 AND version = ?2",
     604              :           -1, &res, nullptr)
     605              :           != SQLITE_OK
     606            0 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     607            0 :       || 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            0 :   sqlite3_finalize (res);
     614              : 
     615            0 :   if (!set_transaction (false))
     616            0 :     throw std::runtime_error ("Failed to end transaction.");
     617            0 : }
     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            0 : MLServiceDB::get_model (const std::string name, const gint version, gchar **model)
     627              : {
     628            0 :   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            0 :   char *value = nullptr;
     632              :   sqlite3_stmt *res;
     633              : 
     634            0 :   if (name.empty () || !model)
     635            0 :     throw std::invalid_argument ("Invalid name or model parameters!");
     636              : 
     637            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     638            0 :   key_with_prefix += name;
     639              : 
     640              :   /* check the existence of given model */
     641            0 :   guint ver = (version > 0) ? version : 0U;
     642            0 :   if (!is_model_registered (key_with_prefix, ver)) {
     643            0 :     throw std::invalid_argument ("Failed to check the existence of " + name);
     644              :   }
     645              : 
     646            0 :   if (version == 0)
     647            0 :     sql = g_strdup_printf (
     648              :         "SELECT json_group_array(%s) FROM tblModel WHERE key = ?1", model_info_json);
     649            0 :   else if (version == -1)
     650            0 :     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            0 :   else if (version > 0)
     653            0 :     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            0 :   if (sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) == SQLITE_OK
     659            0 :       && sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) == SQLITE_OK
     660            0 :       && sqlite3_step (res) == SQLITE_ROW)
     661            0 :     value = g_strdup_printf ("%s", sqlite3_column_text (res, 0));
     662              : 
     663            0 :   sqlite3_finalize (res);
     664            0 :   g_free (sql);
     665              : 
     666            0 :   if (value) {
     667            0 :     *model = value;
     668              :   } else {
     669            0 :     throw std::invalid_argument ("Failed to get model with name " + name
     670            0 :                                  + " and version " + std::to_string (version));
     671              :   }
     672            0 : }
     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            0 : MLServiceDB::delete_model (const std::string name, const guint version, const gboolean force)
     682              : {
     683              :   char *sql;
     684              :   sqlite3_stmt *res;
     685              : 
     686            0 :   if (name.empty ())
     687            0 :     throw std::invalid_argument ("Invalid name parameters!");
     688              : 
     689            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_model_");
     690            0 :   key_with_prefix += name;
     691              : 
     692              :   /* existence check */
     693            0 :   if (!is_model_registered (key_with_prefix, version)) {
     694            0 :     throw std::invalid_argument ("There is no model with name " + name
     695            0 :                                  + " and version " + std::to_string (version));
     696              :   }
     697              : 
     698            0 :   if (version > 0U) {
     699            0 :     if (force)
     700            0 :       ml_logw ("The model with name %s and version %u may be activated, delete it from ml-service.",
     701              :           name.c_str (), version);
     702            0 :     else if (is_model_activated (key_with_prefix, version))
     703            0 :       throw std::invalid_argument ("The model with name " + name
     704            0 :                                    + " and version " + std::to_string (version)
     705            0 :                                    + " is activated, cannot delete it.");
     706              : 
     707            0 :     sql = g_strdup_printf ("DELETE FROM tblModel WHERE key = ?1 and version = %u", version);
     708              :   } else {
     709            0 :     sql = g_strdup ("DELETE FROM tblModel WHERE key = ?1");
     710              :   }
     711              : 
     712            0 :   if (sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     713            0 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     714            0 :       || 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            0 :   sqlite3_finalize (res);
     722            0 :   g_free (sql);
     723              : 
     724            0 :   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            0 : }
     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            0 : 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            0 :   if (name.empty () || path.empty ())
     744            0 :     throw std::invalid_argument ("Invalid name or path parameter!");
     745              : 
     746            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_resource_");
     747            0 :   key_with_prefix += name;
     748              : 
     749            0 :   if (!set_transaction (true))
     750            0 :     throw std::runtime_error ("Failed to begin transaction.");
     751              : 
     752            0 :   if (sqlite3_prepare_v2 (_db,
     753              :           "INSERT OR REPLACE INTO tblResource VALUES (?1, ?2, ?3, ?4)", -1, &res, nullptr)
     754              :           != SQLITE_OK
     755            0 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     756            0 :       || sqlite3_bind_text (res, 2, path.c_str (), -1, nullptr) != SQLITE_OK
     757            0 :       || sqlite3_bind_text (res, 3, description.c_str (), -1, nullptr) != SQLITE_OK
     758            0 :       || sqlite3_bind_text (res, 4, app_info.c_str (), -1, nullptr) != SQLITE_OK
     759            0 :       || 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            0 :   sqlite3_finalize (res);
     765              : 
     766            0 :   if (!set_transaction (false))
     767            0 :     throw std::runtime_error ("Failed to end transaction.");
     768              : 
     769            0 :   long long int last_id = sqlite3_last_insert_rowid (_db);
     770            0 :   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            0 : }
     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            0 : MLServiceDB::get_resource (const std::string name, gchar **resource)
     783              : {
     784            0 :   const char res_info_json[]
     785              :       = "json_object('path', path, 'description', description, 'app_info', app_info)";
     786              :   char *sql;
     787            0 :   char *value = nullptr;
     788              :   sqlite3_stmt *res;
     789              : 
     790            0 :   if (name.empty () || !resource)
     791            0 :     throw std::invalid_argument ("Invalid name or resource parameters!");
     792              : 
     793            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_resource_");
     794            0 :   key_with_prefix += name;
     795              : 
     796              :   /* existence check */
     797            0 :   if (!is_resource_registered (key_with_prefix))
     798            0 :     throw std::invalid_argument ("There is no resource with name " + name);
     799              : 
     800              :   /* Get json string with insertion order. */
     801            0 :   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            0 :   if (sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) == SQLITE_OK
     805            0 :       && sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) == SQLITE_OK
     806            0 :       && sqlite3_step (res) == SQLITE_ROW)
     807            0 :     value = g_strdup_printf ("%s", sqlite3_column_text (res, 0));
     808              : 
     809            0 :   sqlite3_finalize (res);
     810            0 :   g_free (sql);
     811              : 
     812            0 :   if (!value)
     813            0 :     throw std::invalid_argument ("Failed to get resource with name " + name);
     814              : 
     815            0 :   *resource = value;
     816            0 : }
     817              : 
     818              : /**
     819              :  * @brief Delete the resource.
     820              :  * @param[in] name The unique name to delete.
     821              :  */
     822              : void
     823            0 : MLServiceDB::delete_resource (const std::string name)
     824              : {
     825              :   char *sql;
     826              :   sqlite3_stmt *res;
     827              : 
     828            0 :   if (name.empty ())
     829            0 :     throw std::invalid_argument ("Invalid name parameters!");
     830              : 
     831            0 :   std::string key_with_prefix = DB_KEY_PREFIX + std::string ("_resource_");
     832            0 :   key_with_prefix += name;
     833              : 
     834              :   /* existence check */
     835            0 :   if (!is_resource_registered (key_with_prefix))
     836            0 :     throw std::invalid_argument ("There is no resource with name " + name);
     837              : 
     838            0 :   sql = g_strdup ("DELETE FROM tblResource WHERE key = ?1");
     839              : 
     840            0 :   if (sqlite3_prepare_v2 (_db, sql, -1, &res, nullptr) != SQLITE_OK
     841            0 :       || sqlite3_bind_text (res, 1, key_with_prefix.c_str (), -1, nullptr) != SQLITE_OK
     842            0 :       || 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            0 :   sqlite3_finalize (res);
     849            0 :   g_free (sql);
     850              : 
     851            0 :   if (sqlite3_changes (_db) == 0)
     852            0 :     throw std::invalid_argument ("There is no resource with name " + name);
     853            0 : }
     854              : 
     855              : static MLServiceDB *g_svcdb_instance = nullptr;
     856              : 
     857              : /**
     858              :  * @brief Get the service-db instance.
     859              :  */
     860              : static MLServiceDB *
     861            0 : svcdb_get (void)
     862              : {
     863            0 :   g_assert (g_svcdb_instance);
     864            0 :   return g_svcdb_instance;
     865              : }
     866              : 
     867              : G_BEGIN_DECLS
     868              : /**
     869              :  * @brief Initialize the service-db.
     870              :  */
     871              : void
     872            0 : svcdb_initialize (const gchar *path)
     873              : {
     874            0 :   if (g_svcdb_instance) {
     875            0 :     ml_logw ("ML service DB is already opened, close old DB.");
     876            0 :     delete g_svcdb_instance;
     877              :   }
     878              : 
     879            0 :   g_svcdb_instance = new MLServiceDB (path);
     880            0 :   g_assert (g_svcdb_instance);
     881            0 :   g_svcdb_instance->connectDB ();
     882            0 : }
     883              : 
     884              : /**
     885              :  * @brief Close the service-db.
     886              :  */
     887              : void
     888            0 : svcdb_finalize (void)
     889              : {
     890            0 :   if (g_svcdb_instance) {
     891            0 :     g_svcdb_instance->disconnectDB ();
     892            0 :     delete g_svcdb_instance;
     893              :   }
     894              : 
     895            0 :   g_svcdb_instance = nullptr;
     896            0 : }
     897              : 
     898              : /**
     899              :  * @brief Set the pipeline description with given name.
     900              :  * @note If the name already exists, the pipeline description is overwritten.
     901              :  * @param[in] name Unique name to set the associated pipeline description.
     902              :  * @param[in] description The pipeline description to be stored.
     903              :  * @return @c 0 on success. Otherwise a negative error value.
     904              :  */
     905              : gint
     906            0 : svcdb_pipeline_set (const gchar *name, const gchar *description)
     907              : {
     908            0 :   gint ret = 0;
     909            0 :   MLServiceDB *db = svcdb_get ();
     910              : 
     911              :   try {
     912            0 :     db->set_pipeline (name, description);
     913            0 :   } catch (const std::invalid_argument &e) {
     914            0 :     ml_loge ("%s", e.what ());
     915            0 :     ret = -EINVAL;
     916            0 :   } catch (const std::exception &e) {
     917            0 :     ml_loge ("%s", e.what ());
     918            0 :     ret = -EIO;
     919            0 :   }
     920              : 
     921            0 :   return ret;
     922              : }
     923              : 
     924              : /**
     925              :  * @brief Get the pipeline description with given name.
     926              :  * @param[in] name The unique name to retrieve.
     927              :  * @param[out] description The pipeline corresponding with given name.
     928              :  * @return @c 0 on success. Otherwise a negative error value.
     929              :  */
     930              : gint
     931            0 : svcdb_pipeline_get (const gchar *name, gchar **description)
     932              : {
     933            0 :   gint ret = 0;
     934            0 :   MLServiceDB *db = svcdb_get ();
     935              : 
     936              :   try {
     937            0 :     db->get_pipeline (name, description);
     938            0 :   } catch (const std::invalid_argument &e) {
     939            0 :     ml_loge ("%s", e.what ());
     940            0 :     ret = -EINVAL;
     941            0 :   } catch (const std::exception &e) {
     942            0 :     ml_loge ("%s", e.what ());
     943            0 :     ret = -EIO;
     944            0 :   }
     945              : 
     946            0 :   return ret;
     947              : }
     948              : 
     949              : /**
     950              :  * @brief Delete the pipeline description with a given name.
     951              :  * @param[in] name The unique name to delete.
     952              :  * @return @c 0 on success. Otherwise a negative error value.
     953              :  */
     954              : gint
     955            0 : svcdb_pipeline_delete (const gchar *name)
     956              : {
     957            0 :   gint ret = 0;
     958            0 :   MLServiceDB *db = svcdb_get ();
     959              : 
     960              :   try {
     961            0 :     db->delete_pipeline (name);
     962            0 :   } catch (const std::invalid_argument &e) {
     963            0 :     ml_loge ("%s", e.what ());
     964            0 :     ret = -EINVAL;
     965            0 :   } catch (const std::exception &e) {
     966            0 :     ml_loge ("%s", e.what ());
     967            0 :     ret = -EIO;
     968            0 :   }
     969              : 
     970            0 :   return ret;
     971              : }
     972              : 
     973              : /**
     974              :  * @brief Add the model with given name.
     975              :  * @param[in] name Unique name for model.
     976              :  * @param[in] model The model to be stored.
     977              :  * @param[in] is_active The model is active or not.
     978              :  * @param[in] description The model description.
     979              :  * @param[in] app_info The application information.
     980              :  * @param[out] version The version of the model.
     981              :  * @return @c 0 on success. Otherwise a negative error value.
     982              :  */
     983              : gint
     984            0 : svcdb_model_add (const gchar *name, const gchar *path, const bool is_active,
     985              :     const gchar *description, const gchar *app_info, guint *version)
     986              : {
     987            0 :   gint ret = 0;
     988            0 :   MLServiceDB *db = svcdb_get ();
     989              : 
     990              :   try {
     991            0 :     db->set_model (name, path, is_active, description, app_info, version);
     992            0 :   } catch (const std::invalid_argument &e) {
     993            0 :     ml_loge ("%s", e.what ());
     994            0 :     ret = -EINVAL;
     995            0 :   } catch (const std::exception &e) {
     996            0 :     ml_loge ("%s", e.what ());
     997            0 :     ret = -EIO;
     998            0 :   }
     999              : 
    1000            0 :   return ret;
    1001              : }
    1002              : 
    1003              : /**
    1004              :  * @brief Update the model description with given name and version.
    1005              :  * @param[in] name Unique name for model.
    1006              :  * @param[in] version The version of the model.
    1007              :  * @param[in] description The model description.
    1008              :  * @return @c 0 on success. Otherwise a negative error value.
    1009              :  */
    1010              : gint
    1011            0 : svcdb_model_update_description (const gchar *name, const guint version,
    1012              :     const gchar *description)
    1013              : {
    1014            0 :   gint ret = 0;
    1015            0 :   MLServiceDB *db = svcdb_get ();
    1016              : 
    1017              :   try {
    1018            0 :     db->update_model_description (name, version, description);
    1019            0 :   } catch (const std::invalid_argument &e) {
    1020            0 :     ml_loge ("%s", e.what ());
    1021            0 :     ret = -EINVAL;
    1022            0 :   } catch (const std::exception &e) {
    1023            0 :     ml_loge ("%s", e.what ());
    1024            0 :     ret = -EIO;
    1025            0 :   }
    1026              : 
    1027            0 :   return ret;
    1028              : }
    1029              : 
    1030              : /**
    1031              :  * @brief Activate the model with given name.
    1032              :  * @param[in] name Unique name for model.
    1033              :  * @param[in] version The version of the model.
    1034              :  * @return @c 0 on success. Otherwise a negative error value.
    1035              :  */
    1036              : gint
    1037            0 : svcdb_model_activate (const gchar *name, const guint version)
    1038              : {
    1039            0 :   gint ret = 0;
    1040            0 :   MLServiceDB *db = svcdb_get ();
    1041              : 
    1042              :   try {
    1043            0 :     db->activate_model (name, version);
    1044            0 :   } catch (const std::invalid_argument &e) {
    1045            0 :     ml_loge ("%s", e.what ());
    1046            0 :     ret = -EINVAL;
    1047            0 :   } catch (const std::exception &e) {
    1048            0 :     ml_loge ("%s", e.what ());
    1049            0 :     ret = -EIO;
    1050            0 :   }
    1051              : 
    1052            0 :   return ret;
    1053              : }
    1054              : 
    1055              : /**
    1056              :  * @brief Get the model information with given name and version.
    1057              :  * @param[in] name The unique name to retrieve.
    1058              :  * @param[in] version The version of the model. If it is 0, all models will return, if it is -1, return the active model.
    1059              :  * @param[out] model_info The model information.
    1060              :  * @return @c 0 on success. Otherwise a negative error value.
    1061              :  */
    1062              : gint
    1063            0 : svcdb_model_get (const gchar *name, const guint version, gchar **model_info)
    1064              : {
    1065            0 :   gint ret = 0;
    1066            0 :   MLServiceDB *db = svcdb_get ();
    1067              : 
    1068              :   try {
    1069            0 :     db->get_model (name, version, model_info);
    1070            0 :   } catch (const std::invalid_argument &e) {
    1071            0 :     ml_loge ("%s", e.what ());
    1072            0 :     ret = -EINVAL;
    1073            0 :   } catch (const std::exception &e) {
    1074            0 :     ml_loge ("%s", e.what ());
    1075            0 :     ret = -EIO;
    1076            0 :   }
    1077              : 
    1078            0 :   return ret;
    1079              : }
    1080              : 
    1081              : /**
    1082              :  * @brief Get the activated model information with given name.
    1083              :  * @param[in] name The unique name to retrieve.
    1084              :  * @param[out] model_info The model information.
    1085              :  * @return @c 0 on success. Otherwise a negative error value.
    1086              :  */
    1087              : gint
    1088            0 : svcdb_model_get_activated (const gchar *name, gchar **model_info)
    1089              : {
    1090            0 :   gint ret = 0;
    1091            0 :   MLServiceDB *db = svcdb_get ();
    1092              : 
    1093              :   try {
    1094            0 :     db->get_model (name, -1, model_info);
    1095            0 :   } catch (const std::invalid_argument &e) {
    1096            0 :     ml_loge ("%s", e.what ());
    1097            0 :     ret = -EINVAL;
    1098            0 :   } catch (const std::exception &e) {
    1099            0 :     ml_loge ("%s", e.what ());
    1100            0 :     ret = -EIO;
    1101            0 :   }
    1102              : 
    1103            0 :   return ret;
    1104              : }
    1105              : 
    1106              : /**
    1107              :  * @brief Get the model information with given name.
    1108              :  * @param[in] name The unique name to retrieve.
    1109              :  * @param[out] model_info The model information.
    1110              :  * @return @c 0 on success. Otherwise a negative error value.
    1111              :  */
    1112              : gint
    1113            0 : svcdb_model_get_all (const gchar *name, gchar **model_info)
    1114              : {
    1115            0 :   gint ret = 0;
    1116            0 :   MLServiceDB *db = svcdb_get ();
    1117              : 
    1118              :   try {
    1119            0 :     db->get_model (name, 0, model_info);
    1120            0 :   } catch (const std::invalid_argument &e) {
    1121            0 :     ml_loge ("%s", e.what ());
    1122            0 :     ret = -EINVAL;
    1123            0 :   } catch (const std::exception &e) {
    1124            0 :     ml_loge ("%s", e.what ());
    1125            0 :     ret = -EIO;
    1126            0 :   }
    1127              : 
    1128            0 :   return ret;
    1129              : }
    1130              : 
    1131              : /**
    1132              :  * @brief Delete the model.
    1133              :  * @param[in] name The unique name to delete.
    1134              :  * @param[in] version The version of the model to delete.
    1135              :  * @param[in] force If the force is set to @c TRUE, the target model will be forced to delete.
    1136              :  * @return @c 0 on success. Otherwise a negative error value.
    1137              :  */
    1138              : gint
    1139            0 : svcdb_model_delete (const gchar *name, const guint version, const gboolean force)
    1140              : {
    1141            0 :   gint ret = 0;
    1142            0 :   MLServiceDB *db = svcdb_get ();
    1143              : 
    1144              :   try {
    1145            0 :     db->delete_model (name, version, force);
    1146            0 :   } catch (const std::invalid_argument &e) {
    1147            0 :     ml_loge ("%s", e.what ());
    1148            0 :     ret = -EINVAL;
    1149            0 :   } catch (const std::exception &e) {
    1150            0 :     ml_loge ("%s", e.what ());
    1151            0 :     ret = -EIO;
    1152            0 :   }
    1153              : 
    1154            0 :   return ret;
    1155              : }
    1156              : 
    1157              : /**
    1158              :  * @brief Set the resource with given name.
    1159              :  * @param[in] name Unique name of ml-resource.
    1160              :  * @param[in] path The path to be stored.
    1161              :  * @param[in] description The description for ml-resource.
    1162              :  * @param[in] app_info The application information.
    1163              :  * @return @c 0 on success. Otherwise a negative error value.
    1164              :  */
    1165              : gint
    1166            0 : svcdb_resource_add (const gchar *name, const gchar *path,
    1167              :     const gchar *description, const gchar *app_info)
    1168              : {
    1169            0 :   gint ret = 0;
    1170            0 :   MLServiceDB *db = svcdb_get ();
    1171              : 
    1172              :   try {
    1173            0 :     db->set_resource (name, path, description, app_info);
    1174            0 :   } catch (const std::invalid_argument &e) {
    1175            0 :     ml_loge ("%s", e.what ());
    1176            0 :     ret = -EINVAL;
    1177            0 :   } catch (const std::exception &e) {
    1178            0 :     ml_loge ("%s", e.what ());
    1179            0 :     ret = -EIO;
    1180            0 :   }
    1181              : 
    1182            0 :   return ret;
    1183              : }
    1184              : 
    1185              : /**
    1186              :  * @brief Get the resource with given name.
    1187              :  * @param[in] name The unique name to retrieve.
    1188              :  * @param[out] resource The resource information.
    1189              :  * @return @c 0 on success. Otherwise a negative error value.
    1190              :  */
    1191              : gint
    1192            0 : svcdb_resource_get (const gchar *name, gchar **res_info)
    1193              : {
    1194            0 :   gint ret = 0;
    1195            0 :   MLServiceDB *db = svcdb_get ();
    1196              : 
    1197              :   try {
    1198            0 :     db->get_resource (name, res_info);
    1199            0 :   } catch (const std::invalid_argument &e) {
    1200            0 :     ml_loge ("%s", e.what ());
    1201            0 :     ret = -EINVAL;
    1202            0 :   } catch (const std::exception &e) {
    1203            0 :     ml_loge ("%s", e.what ());
    1204            0 :     ret = -EIO;
    1205            0 :   }
    1206              : 
    1207            0 :   return ret;
    1208              : }
    1209              : 
    1210              : /**
    1211              :  * @brief Delete the resource.
    1212              :  * @param[in] name The unique name to delete.
    1213              :  * @return @c 0 on success. Otherwise a negative error value.
    1214              :  */
    1215              : gint
    1216            0 : svcdb_resource_delete (const gchar *name)
    1217              : {
    1218            0 :   gint ret = 0;
    1219            0 :   MLServiceDB *db = svcdb_get ();
    1220              : 
    1221              :   try {
    1222            0 :     db->delete_resource (name);
    1223            0 :   } catch (const std::invalid_argument &e) {
    1224            0 :     ml_loge ("%s", e.what ());
    1225            0 :     ret = -EINVAL;
    1226            0 :   } catch (const std::exception &e) {
    1227            0 :     ml_loge ("%s", e.what ());
    1228            0 :     ret = -EIO;
    1229            0 :   }
    1230              : 
    1231            0 :   return ret;
    1232              : }
    1233              : G_END_DECLS
        

Generated by: LCOV version 2.0-1