{"id":15374884,"url":"https://github.com/babelouest/hoel","last_synced_at":"2025-04-15T11:32:50.877Z","repository":{"id":83736651,"uuid":"47929679","full_name":"babelouest/hoel","owner":"babelouest","description":"C Database abstraction library with json based language","archived":false,"fork":false,"pushed_at":"2024-03-04T23:16:13.000Z","size":846,"stargazers_count":44,"open_issues_count":1,"forks_count":14,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-28T20:51:26.009Z","etag":null,"topics":["backend","c","database","json","mariadb","mysql","ormlite","postgre-sql","sqlite3"],"latest_commit_sha":null,"homepage":"https://babelouest.github.io/hoel/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/babelouest.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2015-12-13T17:46:40.000Z","updated_at":"2024-11-23T07:52:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"63536b76-ccbf-4e3c-9665-27b07df35ab7","html_url":"https://github.com/babelouest/hoel","commit_stats":null,"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/babelouest%2Fhoel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/babelouest%2Fhoel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/babelouest%2Fhoel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/babelouest%2Fhoel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/babelouest","download_url":"https://codeload.github.com/babelouest/hoel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249061202,"owners_count":21206467,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","c","database","json","mariadb","mysql","ormlite","postgre-sql","sqlite3"],"created_at":"2024-10-01T14:00:04.178Z","updated_at":"2025-04-15T11:32:50.578Z","avatar_url":"https://github.com/babelouest.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hoel\n\n![.github/workflows/ccpp.yml](https://github.com/babelouest/hoel/workflows/.github/workflows/ccpp.yml/badge.svg)\n\nDatabase abstraction library written in C.\n\nSimple and easy to use database access library. Works with SQLite 3, MariaDB and PostgreSQL databases. Uses a JSON-based language with `jansson` to execute simple queries based on one table.\n\n# Online documentation\n\nSee the [online documentation](https://babelouest.github.io/hoel/) for a doxygen format of the API documentation.\n\n# Installation\n\n## Prerequisites\n\n### Jansson\n\nInstall [Jansson](http://www.digip.org/jansson/) library for JSON manipulation, minimum version 2.4. On a Debian-based platform, run the following command:\n\n```shell\n$ sudo apt-get install libjansson-dev\n```\n\n### Database libraries\n\nInstall Hoel database dependencies based on your requirements:\n- SQLite3: Install the package `libsqlite3-dev`\n- MariaDB: Install the package `libmariadb-dev`\n- PostgreSQL: Install the package `libpq-dev`\n\n### Distribution packages\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/hoel.svg)](https://repology.org/metapackage/hoel)\n\nHoel is available in multiple distributions as official package. Check out your distribution documentation to install the package automatically.\n\n```shell\n$ # Example for Debian testing\n$ sudo apt install libhoel-dev\n```\n\n## Install from the source\n\n### CMake - Multi architecture\n\n[CMake](https://cmake.org/download/) minimum 3.5 is required.\n\nLast Hoel release: [https://github.com/babelouest/hoel/releases/latest/](https://github.com/babelouest/hoel/releases/latest/)\n\nRun the CMake script in a sub-directory, example:\n\n```shell\n$ cd \u003choel_source\u003e\n$ mkdir build\n$ cd build\n$ cmake ..\n$ make \u0026\u0026 sudo make install\n```\n\nThe available options for CMake are:\n- `-DWITH_SQLITE3=[on|off]` (default `on`): Enable/disable SQLite3 database backend\n- `-DWITH_MARIADB=[on|off]` (default `on`): Enable/disable MariaDB database backend\n- `-DWITH_PGSQL=[on|off]` (default `on`): Enable/disable PostgreSQL database backend\n- `-DWITH_JOURNALD=[on|off]` (default `on`): Build with journald (SystemD) support for logging\n- `-DBUILD_STATIC=[on|off]` (default `off`): Build the static archive in addition to the shared library\n- `-DBUILD_HOEL_TESTING=[on|off]` (default `off`): Build unit tests\n- `-DBUILD_HOEL_DOCUMENTATION=[on|off]` (default `off`): Build the documentation, doxygen is required\n- `-DINSTALL_HEADER=[on|off]` (default `on`): Install header file `hoel.h`\n- `-DBUILD_RPM=[on|off]` (default `off`): Build RPM package when running `make package`\n- `-DCMAKE_BUILD_TYPE=[Debug|Release]` (default `Release`): Compile with debugging symbols or not\n\n### Good ol' Makefile\n\nClone, compile and install [Orcania](https://github.com/babelouest/orcania) and [Yder](https://github.com/babelouest/yder) libraries.\n\n\n### Orcania (Miscellaneous functions)\n\nLast Orcania release: [https://github.com/babelouest/orcania/releases/latest/](https://github.com/babelouest/orcania/releases/latest/)\n\n```shell\n$ cd orcania/src\n$ make \u0026\u0026 sudo make install\n```\n\n### Yder (simple logs library)\n\nLast Yder release: [https://github.com/babelouest/yder/releases/latest/](https://github.com/babelouest/yder/releases/latest/)\n\n```shell\n$ cd yder/src\n$ make\n$ sudo make install\n```\n\n### Hoel\n\nLast Hoel release: [https://github.com/babelouest/hoel/releases/latest/](https://github.com/babelouest/hoel/releases/latest/)\n\n```shell\n$ cd hoel/src\n$ make\n$ sudo make install\n```\n\nBy default, Hoel is compiled with the 3 databases support. If you don't need one or more database, follow these instructions\n\n#### SQLite 3\n\nAdd DISABLE_SQLITE=1 to the `make` command:\n\n```shell\n$ cd hoel/src\n$ make DISABLE_SQLITE=1\n$ sudo make install\n```\n\n#### MariaDB\n\nAdd DISABLE_MARIADB=1 to the `make` command:\n\n```shell\n$ cd hoel/src\n$ make DISABLE_MARIADB=1\n$ sudo make install\n```\n\n#### Postgre SQL\n\nAdd DISABLE_POSTGRESQL=1 to the `make` command:\n\n```shell\n$ cd hoel/src\n$ make DISABLE_POSTGRESQL=1\n$ sudo make install\n```\n\n### Disable 2 backends\n\nYou can disable 2 databases backends to keep just one, simply add both parameters to the `make` command:\n\n```shell\n$ cd hoel/src\n$ make DISABLE_MARIADB=1 DISABLE_POSTGRESQL=1\n$ sudo make install\n```\n\n### Installation folder\n\nBy default, the shared library and the header file will be installed in the `/usr/local` location. To change this setting, you can modify the `DESTDIR` value in the `src/Makefile`.\n\n# API Documentation\n\n## Header files and compilation\n\nTo use Hoel in your code, include the file `hoel.h`.\n\n```c\n#include \u003choel.h\u003e\n```\n\nUse the flag `-lhoel` to include Hoel library in the linking process.\n\n### Return values\n\nWhen specified, some functions return `H_OK` on success, and other values otherwise. `H_OK` is 0, other values are non-0 values. The defined errors list is the following:\n\n```c\n#define H_OK                0  // No error\n#define H_ERROR             1  // Generic error\n#define H_ERROR_PARAMS      2  // Error in input parameters\n#define H_ERROR_CONNECTION  3  // Error in database connection\n#define H_ERROR_DISABLED    4  // Database connection is disabled\n#define H_ERROR_QUERY       5  // Error executing query\n#define H_ERROR_MEMORY      99 // Error allocating memory\n```\n\n### Memory allocation\n\nSome function return allocated values. When the value is not a structure, you must use the function `h_free` to clean it. Otherwise, use the dedicated functions.\n\n```c\n/**\n * free data allocated by hoel functions\n */\nvoid h_free(void * data);\n```\n\n### Initialization\n\nTo create a connection to a database, use its dedicated function\n\n```c\n/**\n * h_connect_sqlite\n * Opens a database connection to a sqlite3 db file\n * return pointer to a struct _h_connection * on sucess, NULL on error\n */\nstruct _h_connection * h_connect_sqlite(const char * db_path);\n\n/**\n * h_connect_mariadb\n * Opens a database connection to a mariadb server\n * return pointer to a struct _h_connection * on success, NULL on error\n */\nstruct _h_connection * h_connect_mariadb(const char * host, const char * user, const char * passwd, const char * db, const unsigned int port, const char * unix_socket);\n\n/**\n * h_connect_pgsql\n * Opens a database connection to a PostgreSQL server\n * return pointer to a struct _h_connection * on sucess, NULL on error\n */\nstruct _h_connection * h_connect_pgsql(char * conninfo);\n```\n\nAll these functions return a struct _h_connection * on success. This pointer will be needed on every call to Hoel functions.\n\nWhen you no longer need your connection, close it using the function `h_close_db`. This will close the connection to the database and free the memory allocated by the connection.\n\n```c\n/**\n * Close a database connection\n * return H_OK on success\n */\nint h_close_db(struct _h_connection * conn);\n```\n\nThe connection must be cleaned when it's no longer needed.\n\n```c\n/**\n * h_clean_connection\n * free memory allocated by the struct _h_connection\n * return H_OK on success\n */\nint h_clean_connection(struct _h_connection * conn);\n```\n\n### Escape string\n\nIf you need to escape parameters, you can use the functions `h_escape_string`, the returned value must be h_free'd after use.\n\nThe meaning of existence of the function `h_escape_string_with_quotes` is because of PostgreSQL ways to escape an unsafe string.\n\nTL;DR:\n- Use `h_escape_string_with_quotes` only if you use a PostgreSQL database.\n- You can use both `h_escape_string_with_quotes` and `h_escape_string` if you use only SQLite3 and/or MariaDB databases.\n\nIf the unsafe string contains backslashes `\"\\\"`, the escaped string will have the pattern `E'\u003csafe\u003e'`, otherwise it will have the pattern `'\u003csafe\u003e'`. Since the function `h_escape_string` must return the safe string only, without surroundings quotes `'`, the format `E'\u003csafe\u003e'`  is incompatible with Hoel API.\n\nTherefore, using `h_escape_string` with PostgreSQL could lead to undefined behaviour and more importantly exploitable bugs.\n\nTo avoid this, on a PostgreSQL database, an escaped string using `h_escape_string` that should return the format `E'\u003csafe\u003e'` will return `NULL`, and an escaped string using `h_escape_string_with_quotes` will return the format `E'\u003csafe\u003e'`.\n\n```c\n/**\n * h_escape_string\n * Escapes a string\n * returned value must be h_free'd after use\n */\nchar * h_escape_string(const struct _h_connection * conn, const char * unsafe);\n\n/**\n * h_escape_string_with_quotes\n * Escapes a string and returns it ready to be inserted in the query\n * returned value must be h_h_free'd after use\n */\nchar * h_escape_string_with_quotes(const struct _h_connection * conn, const char * unsafe);\n```\n\n### Build a more complicated where clause\n\nWhen you need to run a query with a where clause using multiple parameters, such as `WHERE col1='a' AND (col2='b' OR col3=5) AND col4=42.3`, you can use the operator `raw`:\n\n```JSON\n{\n  \"table\": \"table1\",\n  \"columns\": [\"col1\", \"col2\"]\n  \"where\": {\n    \" \": {\n      \"operator\", \"raw\",\n      \"value\", \"col1='a' AND (col2='b' or col3='c') AND col4=5\"\n    }\n  }\n}\n```\n\nIn some cases, you may need to build the where clause with multiple variables. In hoel 1.4.27, the function `h_build_where_clause` was introduced to help that. Please note that this function is still in Beta.\n\n```C\n/**\n * h_build_where_clause\n * Generates a where clause based on the pattern and the values given\n * @param conn the connection to the database\n * @param pattern the pattern to build the where clause\n * the pattern variables available are the following:\n * - %s: a string value to escape with quotes\n * - %S: a string value to escape without quotes\n * - %c: a string value not to escape with quotes\n * - %C: a string value not to escape without quotes\n * - %d: an integer value in json_int_t format\n * - %f: a double value\n * - %j: a json_t value, the value must be of the type JSON_INTEGER, JSON_REAL or JSON_STRING, string values will be escaped with quotes\n * - %%: the value '%'\n * @return a heap-allocated string\n * returned value must be h_free'd after use\n */\nchar * h_build_where_clause(const struct _h_connection * conn, const char * pattern, ...);\n```\n\nThen, to build the where clause above using `h_build_where_clause`, you can use the following code:\n\n```C\nconst char col1[] = \"a\", col2[] = \"b\";\njson_int_t col3 = 5;\ndouble col4 = 42.3;\nchar * where_clause = h_build_where_clause(\"col1=%s AND (col2='S' OR col3=%d) AND col4=%f\", col1, col2, col3, col4);\njson_t * j_query = json_pack(\"{sss[ss]s{s{ssss}}}\",\n                             \"table\", \"table1\",\n                             \"columns\",\n                               \"col1\",\n                               \"col2\",\n                             \"where\",\n                               \" \",\n                                 \"operator\", \"raw\",\n                                 \"value\", where_clause);\nh_free(where_clause);\n// Execute j_query\n```\n\nNote that if you use constant litteral for integer or double values, you should cast them first:\n\n```C\nconst char col1[] = \"a\", col2[] = \"b\";\nchar * where_clause = h_build_where_clause(\"col1=%s AND (col2='S' OR col3=%d) AND col4=%f\", col1, col2, (json_int_t)5, (double)42.3);\n```\n\n### Execute a SQL query\n\nTo execute a SQL query, you can use the function `h_execute_query` which will run the query in the database specified by the parameter `conn`. If a `result` parameter is specified, the result of the query (if any) will be stored in the `result` structure.\n\n```c\n/**\n * h_execute_query\n * Execute a query, set the result structure with the returned values if available\n * if result is NULL, the query is executed but no value will be returned\n * options available\n * H_OPTION_NONE (0): no option\n * H_OPTION_SELECT: Execute a prepare statement (sqlite only)\n * H_OPTION_EXEC: Execute an exec statement (sqlite only)\n * return H_OK on success\n */\nint h_execute_query(const struct _h_connection * conn, const char * query, struct _h_result * result, int options);\n```\n\n### Result structure\n\nThe `struct _h_result` is a structure containing the values returned by a query. The definition of the structure is:\n\n```c\n/**\n * sql result structure\n */\nstruct _h_result {\n  unsigned int nb_rows;\n  unsigned int nb_columns;\n  struct _h_data ** data;\n};\n```\n\nThe data value is a 2 dimensional array with `struct _h_data` variables. A `struct _h_data` is defined as:\n\n```c\n/**\n * sql data container\n */\nstruct _h_data {\n  int type;\n  void * t_data;\n};\n```\n\nwhere `type` can be the following values:\n\n```c\n#define HOEL_COL_TYPE_INT    0\n#define HOEL_COL_TYPE_DOUBLE 1\n#define HOEL_COL_TYPE_TEXT   2\n#define HOEL_COL_TYPE_DATE   3\n#define HOEL_COL_TYPE_BLOB   4\n#define HOEL_COL_TYPE_NULL   5\n```\n\n`t_data` will point to a `struct _h_type_*` corresponding to the type. The `struct _h_type_*` available are:\n\n```c\n/**\n * sql value integer type\n */\nstruct _h_type_int {\n  int value;\n};\n\n/**\n * sql value double type\n */\nstruct _h_type_double {\n  double value;\n};\n\n/**\n * sql value date/time type\n */\nstruct _h_type_datetime {\n  struct tm value;\n};\n\n/**\n * sql value string type\n */\nstruct _h_type_text {\n  char * value;\n};\n\n/**\n * sql value blob type\n */\nstruct _h_type_blob {\n  size_t length;\n  void * value;\n};\n```\n\n### Clean results or data\n\nTo clean a result or a data structure, you can use its dedicated functions:\n\n```c\n/**\n * h_clean_result\n * Free all the memory allocated by the struct _h_result\n * return H_OK on success\n */\nint h_clean_result(struct _h_result * result);\n\n/**\n * h_clean_data\n * Free memory allocated by the struct _h_data\n * return H_OK on success\n */\nint h_clean_data(struct _h_data * data);\n```\n\n### Get last id inserted\n\nIf you need the last id generated after an insert query, you can use the following function:\n\n```c\n/**\n * h_query_last_insert_id\n * return the id of the last inserted value\n * return a pointer to `struct _h_data *` on success, NULL otherwise.\n */\nstruct _h_data * h_query_last_insert_id(const struct _h_connection * conn);\n```\n\n### Additional query functions\n\nYou can use additional functions for specific needs. All these function will use `h_execute_query` but check input parameters before.\n\n```c\n/**\n * h_query_insert\n * Execute an insert query\n * return H_OK on success\n */\nint h_query_insert(const struct _h_connection * conn, const char * query);\n\n/**\n * h_query_update\n * Execute an update query\n * return H_OK on success\n */\nint h_query_update(const struct _h_connection * conn, const char * query);\n\n/**\n * h_query_delete\n * Execute an delete query\n * return H_OK on success\n */\nint h_query_delete(const struct _h_connection * conn, const char * query);\n\n/**\n * h_execute_query\n * Execute a select query, set the result structure with the returned values\n * return H_OK on success\n */\nint h_query_select(const struct _h_connection * conn, const char * query, struct _h_result * result);\n```\n\n### Simple JSON queries\n\nHoel allows to use JSON objects for simple queries with `jansson` library. In the simple JSON queries, a JSON object called `json_t * j_query` is used to generate the query.\n\nAll `json_t *` returned and updated values must be free after use.\n\nA `j_query` has the following form:\n```javascript\n * {\n *   \"table\": \"table_name\"             // String, mandatory, the table name where the query is executed\n *   \"columns\": [\"col1\", \"col2\"]       // Array of strings, available for h_select, optional. If not specified, * will be used, the columns values are not escaped by the library\n *   \"order_by\": \"col_name [asc|desc]\" // String, available for h_select, specify the order by clause, optional, the value is not escaped by the library\n *   \"limit\": integer_value            // Integer, available for h_select, specify the limit value, optional\n *   \"offset\"                          // Integer, available for h_select, specify the limit value, optional but available only if limit is set\n *   \"values\": [{                      // json object or json array of json objects, available for h_insert, mandatory, specify the values to update\n *     \"col1\": \"value1\",               // Generates col1='value1' for an update query\n *     \"col2\": value_integer,          // Generates col2=value_integer for an update query\n *     \"col3\", \"value3\",               // Generates col3='value3' for an update query\n *     \"col4\", null                    // Generates col4=NULL for an update query\n *   }]\n *   \"set\": {                          // json object, available for h_update, mandatory, specify the values to update\n *     \"col1\": \"value1\",               // Generates col1='value1' for an update query\n *     \"col2\": value_integer,          // Generates col2=value_integer for an update query\n *     \"col3\", \"value3\",               // Generates col3='value3' for an update query\n *     \"col4\", null                    // Generates col4=NULL for an update query\n *   }\n *   \"where\": {                        // json object, available for h_select, h_update and h_delete, mandatory, specify the where clause. All clauses are separated with an AND operator\n *     \"col1\": \"value1\",               // Generates col1='value1'\n *     \"col2\": value_integer,          // Generates col2=value_integer\n *     \"col3\": null,                   // Generates col3=NULL\n *     \"col4\", {                       // Generates col4\u003c12\n *       \"operator\": \"\u003c\",\n *       \"value\": 12\n *     },\n *     \"col5\", {                       // Generates col5 IS NOT NULL\n *       \"operator\": \"NOT NULL\"\n *     },\n *     \"col6\", {                       // Generates col6 LIKE '%value6%'\n *       \"operator\": \"raw\",\n *       \"value\": \"LIKE '%value6%'\"\n *     }\n *   }\n * }\n```\n\n#### Where clause construction\n\nA `where` clause is a JSON object containing a series of clauses. A clause can have 2 different forms:\n\n- `col_name: value`\n- `col_name: {operator: \"operator_value\", value: value}`\n\nIn the first case, `col_name: value`, the clause becomes `col_name = value`. Value is always escaped.\n\nIn the second case, `col_name: {operator: \"operator_value\", value: value}`, depending on the `operator` value, the clause can have different forms:\n- `operator: \"NOT NULL\"`, the clause becomes `col_name IS NOT NULL`\n- `operator: \"raw\"`, the `value` value becomes the clause itself, not escaped, for example in `{ \"operator\": \"raw\", \"value\": \"LIKE '%value6%'\" }`, the clause becomes `col6 LIKE '%value6%'`\n- otherwise, the clause becomes `col_name operator value`, value is escaped\n\nAll clauses are separated by an `AND` operator.\n\nAs en example, here is a JSON object and its generated where clause:\n\nJSON object:\n```javascript\n{\n  \"col1\": \"value1\",\n  \"col2\": 42,\n  \"col3\": {\n    \"operator\": \"\u003e=\",\n    \"value\": 55.5\n  },\n  \"col4\": {\n    \"operator\": \"raw\",\n    \"value\": \"LIKE '%alu%'\"\n  }\n}\n```\n\nSQL Where clause:\n```sql\nWHERE col1 = 'value1'\n  AND col2 = 42\n  AND col3 \u003e= 55.5\n  AND col4 LIKE '%alu%'\n```\n\nIf you need less simple clauses, you can build it on your own and use the `h_execute_query` or the `h_execute_query_json` functions.\n\nThe simple JSON queries functions are:\n\n```c\n/**\n * h_select\n * Execute a select query\n * Uses a json_t * parameter for the query parameters\n * Store the result of the query in j_result if specified. j_result must be decref'd after use\n * Duplicate the generated query in generated_query if specified, must be h_free'd after use\n * return H_OK on success\n */\nint h_select(const struct _h_connection * conn, const json_t * j_query, json_t ** j_result, char ** generated_query);\n\n/**\n * h_insert\n * Execute an insert query\n * Uses a json_t * parameter for the query parameters\n * Duplicate the generated query in generated_query if specified, must be h_free'd after use\n * return H_OK on success\n */\nint h_insert(const struct _h_connection * conn, const json_t * j_query, char ** generated_query);\n\n/**\n * h_last_insert_id\n * return the id of the last inserted value\n * return a pointer to `json_t *` on success, NULL otherwise.\n * The returned value is of type JSON_INTEGER\n */\njson_t * h_last_insert_id(const struct _h_connection * conn);\n\n/**\n * h_update\n * Execute an update query\n * Uses a json_t * parameter for the query parameters\n * Duplicate the generated query in generated_query if specified, must be h_free'd after use\n * return H_OK on success\n */\nint h_update(const struct _h_connection * conn, const json_t * j_query, char ** generated_query);\n\n/**\n * h_delete\n * Execute a delete query\n * Uses a json_t * parameter for the query parameters\n * Duplicate the generated query in generated_query if specified, must be h_free'd after use\n * return H_OK on success\n */\nint h_delete(const struct _h_connection * conn, const json_t * j_query, char ** generated_query);\n```\n\n#### JSON last insert id\n\nThe function `h_last_insert_id` returns the last inserted id in a `json_t *` format.\n\n```c\n/**\n * h_last_insert_id\n * return the id of the last inserted value\n * return a pointer to `json_t *` on success, NULL otherwise.\n * The returned value is of type JSON_INTEGER\n */\njson_t * h_last_insert_id(const struct _h_connection * conn);\n```\n\n### Example source code\n\nSee `examples` folder for detailed sample source codes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbabelouest%2Fhoel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbabelouest%2Fhoel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbabelouest%2Fhoel/lists"}