@miatechnet/node-odbc 2.4.16 → 2.4.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/odbc.d.ts CHANGED
@@ -91,8 +91,8 @@ declare namespace odbc {
91
91
  query<T, O extends QueryOptions>(sql: string, options: O, callback: (error: NodeOdbcError, result: O extends CursorQueryOptions ? Cursor : Result<T>) => undefined): undefined;
92
92
  query<T, O extends QueryOptions>(sql: string, parameters: Array<number|string>, options: O, callback: (error: NodeOdbcError, result: O extends CursorQueryOptions ? Cursor : Result<T>) => undefined): undefined;
93
93
 
94
- callProcedure<T>(catalog: string|null, schema: string|null, name: string, callback: (error: NodeOdbcError, result: Result<T>) => undefined): undefined;
95
- callProcedure<T>(catalog: string|null, schema: string|null, name: string, parameters: Array<number|string>, callback: (error: NodeOdbcError, result: Result<T>) => undefined): undefined;
94
+ callProcedure<T>(catalog: string|null, schema: string|null, name: string, callback: (error: NodeOdbcError, result: Array<Result<T>>) => undefined): undefined;
95
+ callProcedure<T>(catalog: string|null, schema: string|null, name: string, parameters: Array<number|string>, callback: (error: NodeOdbcError, result: Array<Result<T>>) => undefined): undefined;
96
96
 
97
97
  createStatement(callback: (error: NodeOdbcError, statement: Statement) => undefined): undefined;
98
98
 
@@ -122,7 +122,7 @@ declare namespace odbc {
122
122
  query<T, O extends QueryOptions>(sql: string, options: O): O extends CursorQueryOptions ? Promise<Cursor> : Promise<Result<T>>;
123
123
  query<T, O extends QueryOptions>(sql: string, parameters: Array<number|string>, options: O): O extends CursorQueryOptions ? Promise<Cursor> : Promise<Result<T>>;
124
124
 
125
- callProcedure<T>(catalog: string|null, schema: string|null, name: string, parameters?: Array<number|string>): Promise<Result<T>>;
125
+ callProcedure<T>(catalog: string|null, schema: string|null, name: string, parameters?: Array<number|string>): Promise<Array<Result<T>>>;
126
126
 
127
127
  createStatement(): Promise<Statement>;
128
128
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@miatechnet/node-odbc",
3
3
  "description": "unixodbc bindings for node - Fork with multi-result set support for stored procedures",
4
- "version": "2.4.16",
4
+ "version": "2.4.19",
5
5
  "homepage": "https://github.com/ppimentela/node-odbc/",
6
6
  "main": "lib/odbc.js",
7
7
  "types": "lib/odbc.d.ts",
@@ -1887,6 +1887,25 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
1887
1887
  return;
1888
1888
  }
1889
1889
 
1890
+ // Skip result sets with no columns (e.g., from INSERT/UPDATE/SET statements)
1891
+ if (data->column_count == 0) {
1892
+ // No columns means this is not a SELECT-like result set, skip it
1893
+ return_code = SQLMoreResults(data->hstmt);
1894
+ if (return_code == SQL_NO_DATA) {
1895
+ hasMoreResults = false;
1896
+ } else if (!SQL_SUCCEEDED(return_code)) {
1897
+ this->errors = GetODBCErrors(SQL_HANDLE_STMT, data->hstmt);
1898
+ SetError("[odbc] Error getting more results\0");
1899
+ return;
1900
+ }
1901
+
1902
+ // Set fetch size for the next result set
1903
+ if (hasMoreResults) {
1904
+ set_fetch_size(data, data->fetch_size);
1905
+ }
1906
+ continue;
1907
+ }
1908
+
1890
1909
  // Obtener todos los datos del result set actual
1891
1910
  return_code = fetch_all_and_store(
1892
1911
  data,
@@ -1906,8 +1925,9 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
1906
1925
  }
1907
1926
 
1908
1927
  // Save the result set with column metadata to allResultSets
1928
+ // Use swap/move to transfer ownership and prevent double-free
1909
1929
  ResultSetData rsData;
1910
- rsData.rows = data->storedRows;
1930
+ rsData.rows.swap(data->storedRows); // Transfer ownership of rows vector
1911
1931
  rsData.columns = data->columns;
1912
1932
  rsData.column_count = data->column_count;
1913
1933
  rsData.bound_columns = data->bound_columns;
@@ -1916,8 +1936,7 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
1916
1936
 
1917
1937
  data->allResultSets.push_back(rsData);
1918
1938
 
1919
- // Clear storedRows and reset pointers (don't free, they're now in allResultSets)
1920
- data->storedRows.clear();
1939
+ // Reset pointers to NULL (ownership transferred to allResultSets)
1921
1940
  data->columns = NULL;
1922
1941
  data->column_count = 0;
1923
1942
  data->bound_columns = NULL;
@@ -1934,6 +1953,11 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
1934
1953
  SetError("[odbc] Error getting more results\0");
1935
1954
  return;
1936
1955
  }
1956
+
1957
+ // Set fetch size for the next result set
1958
+ if (hasMoreResults) {
1959
+ set_fetch_size(data, data->fetch_size);
1960
+ }
1937
1961
  }
1938
1962
  }
1939
1963
 
@@ -1951,8 +1975,9 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
1951
1975
  for (size_t rs_index = 0; rs_index < data->allResultSets.size(); rs_index++) {
1952
1976
  ResultSetData &rsData = data->allResultSets[rs_index];
1953
1977
 
1954
- // Restore column metadata and rows for this result set
1955
- data->storedRows = rsData.rows;
1978
+ // Transfer ownership of rows and column metadata for processing
1979
+ // Use swap to ensure proper ownership transfer
1980
+ data->storedRows.swap(rsData.rows);
1956
1981
  data->columns = rsData.columns;
1957
1982
  data->column_count = rsData.column_count;
1958
1983
  data->bound_columns = rsData.bound_columns;
@@ -1966,8 +1991,7 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
1966
1991
 
1967
1992
  allResults.Set(rs_index, singleResult);
1968
1993
 
1969
- // Mark rows as processed (process_data_for_napi frees them internally)
1970
- data->allResultSets[rs_index].rows.clear();
1994
+ // After process_data_for_napi, rows are freed and storedRows is cleared
1971
1995
  // Mark columns as processed to prevent double-free
1972
1996
  data->allResultSets[rs_index].columns = NULL;
1973
1997
  data->allResultSets[rs_index].bound_columns = NULL;
@@ -1983,6 +2007,25 @@ class CallProcedureAsyncWorker : public ODBCAsyncWorker {
1983
2007
  data->bound_columns = NULL;
1984
2008
  data->row_status_array = NULL;
1985
2009
 
2010
+ // Set metadata properties on the outer allResults array for backward compatibility
2011
+ if (data->sql != NULL) {
2012
+ #ifdef UNICODE
2013
+ allResults.Set(Napi::String::New(env, STATEMENT), Napi::String::New(env, (const char16_t*)data->sql));
2014
+ #else
2015
+ allResults.Set(Napi::String::New(env, STATEMENT), Napi::String::New(env, (const char*)data->sql));
2016
+ #endif
2017
+ } else {
2018
+ allResults.Set(Napi::String::New(env, STATEMENT), env.Null());
2019
+ }
2020
+
2021
+ if (napiParameters.IsEmpty()) {
2022
+ allResults.Set(Napi::String::New(env, PARAMETERS), env.Undefined());
2023
+ } else {
2024
+ allResults.Set(Napi::String::New(env, PARAMETERS), napiParameters.Value());
2025
+ }
2026
+
2027
+ allResults.Set(Napi::String::New(env, RETURN), env.Undefined());
2028
+
1986
2029
  std::vector<napi_value> callbackArguments;
1987
2030
  callbackArguments.push_back(env.Null());
1988
2031
  callbackArguments.push_back(allResults);