@@ -425,6 +425,81 @@ bool SQLite3DB::execute_statement_raw(const char *str, char **error, int *cols,
425425 return ret;
426426}
427427
428+ /* *
429+ * @brief Executes a prepared SQL statement and returns the result set.
430+ *
431+ * @param statement The prepared SQL statement to execute.
432+ * @param _error Pointer to a variable to store the error message.
433+ * @param _cols Pointer to a variable to store the number of columns.
434+ * @param _affected_rows Pointer to a variable to store the number of affected rows.
435+ * @return A pointer to the SQLite3_result object representing the result set.
436+ */
437+ SQLite3_result* SQLite3DB::execute_prepared (sqlite3_stmt* statement, char ** error, int * cols, int * affected_rows) {
438+ SQLite3_result* resultset;
439+
440+ char * myerror;
441+ char ** _error = (error == NULL ? &myerror : error);
442+
443+ int mycols;
444+ int * _cols = (cols == NULL ? &mycols : cols);
445+
446+ int my_affected_rows;
447+ int * _affected_rows = (affected_rows == NULL ? &my_affected_rows : affected_rows);
448+
449+ if (execute_prepared (statement, _error, _cols, _affected_rows, &resultset))
450+ return resultset;
451+
452+ return NULL ;
453+ }
454+
455+ /* *
456+ * @brief Executes a prepared SQL statement and returns the result set.
457+ *
458+ * @param statement The prepared SQLite statement to execute.
459+ * @param error Pointer to a variable to store the error message.
460+ * @param cols Pointer to a variable to store the number of columns.
461+ * @param affected_rows Pointer to a variable to store the number of affected rows.
462+ * @param resultset Pointer to a pointer to a SQLite3_result object representing the result set.
463+ * @return True if the execution was successful, false otherwise.
464+ */
465+ bool SQLite3DB::execute_prepared (sqlite3_stmt* statement, char ** error, int * cols, int * affected_rows, SQLite3_result** resultset) {
466+ int rc;
467+ *error = NULL ;
468+ bool ret = false ;
469+ *cols = (*proxy_sqlite3_column_count)(statement);
470+ if (*cols == 0 ) { // not a SELECT
471+ *resultset = NULL ;
472+ // Get total changes before executing the statement
473+ long long total_changes_before = (*proxy_sqlite3_total_changes64)(db);
474+ do {
475+ rc = (*proxy_sqlite3_step)(statement);
476+ if (rc == SQLITE_LOCKED || rc == SQLITE_BUSY) { // the execution of the prepared statement failed because locked
477+ if ((*proxy_sqlite3_get_autocommit)(db) == 0 ) {
478+ *error = strdup ((*proxy_sqlite3_errmsg)(db));
479+ goto __exit_execute_prepared;
480+ }
481+ usleep (USLEEP_SQLITE_LOCKED);
482+ }
483+ } while (rc == SQLITE_LOCKED || rc == SQLITE_BUSY);
484+ if (rc == SQLITE_DONE) {
485+ // Calculate affected rows as the difference in total changes
486+ long long total_changes_after = (*proxy_sqlite3_total_changes64)(db);
487+ *affected_rows = (int )(total_changes_after - total_changes_before);
488+ ret = true ;
489+ } else {
490+ *error = strdup ((*proxy_sqlite3_errmsg)(db));
491+ goto __exit_execute_prepared;
492+ }
493+ } else {
494+ *affected_rows = 0 ;
495+ *resultset = new SQLite3_result (statement);
496+ ret = true ;
497+ }
498+ __exit_execute_prepared:
499+ // (*proxy_sqlite3_reset)(statement);
500+ return ret;
501+ }
502+
428503/* *
429504 * @brief Executes a SQL statement and returns a single integer result.
430505 *
0 commit comments