From a155c8a3371b5a207752017b329ffdf0846a81c2 Mon Sep 17 00:00:00 2001 From: Peter Keuter Date: Thu, 2 Dec 2021 09:36:56 +0100 Subject: [PATCH] fix: made to work with node 14+ --- .gitignore | 2 + package-lock.json | 42 + package.json | 6 +- src/h/connection.h | 84 +- src/h/errors.h | 18 +- src/h/nodever_cover.h | 17 +- src/h/sacapi.h | 732 +++++++-------- src/h/sacapidll.h | 251 +++--- src/h/sqlany_utils.h | 296 +++---- src/h/stmt.h | 82 +- src/sacapidll.cpp | 247 +++--- src/sqlanywhere.cpp | 1971 ++++++++++++++++++++++------------------- src/utils.cpp | 1708 ++++++++++++++++++----------------- 13 files changed, 2794 insertions(+), 2662 deletions(-) create mode 100644 .gitignore create mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48912d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +node_modules \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8aefbf9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,42 @@ +{ + "name": "sqlanywhere", + "version": "2.0.3", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "sqlanywhere", + "version": "2.0.3", + "hasInstallScript": true, + "dependencies": { + "help": "^3.0.2", + "nan": "^2.15.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/help": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/help/-/help-3.0.2.tgz", + "integrity": "sha1-luGQ1KCkU7icLLSwWrOOOo+f2t0=" + }, + "node_modules/nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + } + }, + "dependencies": { + "help": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/help/-/help-3.0.2.tgz", + "integrity": "sha1-luGQ1KCkU7icLLSwWrOOOo+f2t0=" + }, + "nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + } + } +} diff --git a/package.json b/package.json index 4644056..a9d50af 100644 --- a/package.json +++ b/package.json @@ -2,19 +2,19 @@ "author": "SQL ANYWHERE", "name": "sqlanywhere", "description": "SQL Anywhere JavaScript Driver.", - "version": "1.0.25", + "version": "2.0.3", "repository": { "url": "https://github.com/sqlanywhere/node-sqlanywhere" }, "main": "./lib/index", "engines": { - "node": ">=0.10" + "node": ">=14.0.0" }, "scripts": { "install": "node build.js" }, "dependencies": { "help": "^3.0.2", - "nan": "2.14.2" + "nan": "^2.15.0" } } diff --git a/src/h/connection.h b/src/h/connection.h index d629b94..568cb70 100644 --- a/src/h/connection.h +++ b/src/h/connection.h @@ -136,24 +136,16 @@ using namespace node; */ class Connection : public ObjectWrap { - public: +public: /// @internal -#if v010 - static void Init(); -#else - static void Init( Isolate * ); -#endif + static void Init(Isolate *); /// @internal - static NODE_API_FUNC( NewInstance ); - - private: + static NODE_API_FUNC(NewInstance); + +private: /// @internal -#if v010 - Connection( const Arguments &args ); -#else - Connection( const FunctionCallbackInfo &args ); -#endif + Connection(const FunctionCallbackInfo &args); /// @internal ~Connection(); @@ -161,13 +153,13 @@ class Connection : public ObjectWrap static Persistent constructor; /// @internal - static void noParamAfter( uv_work_t *req ); + static void noParamAfter(uv_work_t *req); /// @internal - static void connectAfter( uv_work_t *req ); + static void connectAfter(uv_work_t *req); /// @internal - static void connectWork( uv_work_t *req ); + static void connectWork(uv_work_t *req); /// @internal - static NODE_API_FUNC( New ); + static NODE_API_FUNC(New); /// Connect using an existing connection. // @@ -202,7 +194,7 @@ class Connection : public ObjectWrap // // @internal /// - + /** Creates a new connection. * * This method creates a new connection using either a connection string @@ -242,7 +234,7 @@ class Connection : public ObjectWrap * * @see Connection::disconnect */ - static NODE_API_FUNC( connect ); + static NODE_API_FUNC(connect); /** Closes the current connection. * @@ -275,11 +267,11 @@ class Connection : public ObjectWrap * * @see Connection::connect */ - static NODE_API_FUNC( disconnect ); - + static NODE_API_FUNC(disconnect); + /// @internal - static void disconnectWork( uv_work_t *req ); - + static void disconnectWork(uv_work_t *req); + /** Executes the specified SQL statement. * * This method takes in a SQL statement and an optional array of bind @@ -335,8 +327,8 @@ class Connection : public ObjectWrap * @return If no callback is specified, the result is returned. * */ - static NODE_API_FUNC( exec ); - + static NODE_API_FUNC(exec); + /** Prepares the specified SQL statement. * * This method prepares a SQL statement and returns a Statement object @@ -373,13 +365,13 @@ class Connection : public ObjectWrap * @return If no callback is specified, a Statement object is returned. * */ - static NODE_API_FUNC( prepare ); - + static NODE_API_FUNC(prepare); + /// @internal - static void prepareAfter( uv_work_t *req ); + static void prepareAfter(uv_work_t *req); /// @internal - static void prepareWork( uv_work_t *req ); - + static void prepareWork(uv_work_t *req); + /** Performs a commit on the connection. * * This method performs a commit on the connection. @@ -421,11 +413,11 @@ class Connection : public ObjectWrap * @param callback The optional callback function. ( type: Function ) * */ - static NODE_API_FUNC( commit ); + static NODE_API_FUNC(commit); /// @internal - static void commitWork( uv_work_t *req ); - + static void commitWork(uv_work_t *req); + /** Performs a rollback on the connection. * * This method performs a rollback on the connection. @@ -465,10 +457,10 @@ class Connection : public ObjectWrap * @param callback The optional callback function. ( type: Function ) * */ - static NODE_API_FUNC( rollback ); + static NODE_API_FUNC(rollback); /// @internal - static void rollbackWork( uv_work_t *req ); + static void rollbackWork(uv_work_t *req); /** Indicates whether the connection is connected. * @@ -492,24 +484,24 @@ class Connection : public ObjectWrap * @return true if the connection is connected, false if not. * */ - static NODE_API_FUNC( connected ); + static NODE_API_FUNC(connected); - public: +public: /// @internal - a_sqlany_connection *conn; + a_sqlany_connection *conn; /// @internal - unsigned int max_api_ver; + unsigned int max_api_ver; /// @internal - bool sqlca_connection; + bool sqlca_connection; /// @internal - uv_mutex_t conn_mutex; + uv_mutex_t conn_mutex; /// @internal - Persistent _arg; + Persistent _arg; /// @internal - std::vector statements; + std::vector statements; /// @internal - void removeStmt( class StmtObject *stmt ); + void removeStmt(class StmtObject *stmt); /// @internal - void cleanupStmts( void ); + void cleanupStmts(void); }; diff --git a/src/h/errors.h b/src/h/errors.h index d0ca4a0..a5c822a 100644 --- a/src/h/errors.h +++ b/src/h/errors.h @@ -1,12 +1,12 @@ // *************************************************************************** // Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. // *************************************************************************** -#define JS_ERR_INVALID_OBJECT -2001 -#define JS_ERR_INVALID_ARGUMENTS -2002 -#define JS_ERR_CONNECTION_ALREADY_EXISTS -2003 -#define JS_ERR_INITIALIZING_DBCAPI -2004 -#define JS_ERR_NOT_CONNECTED -2005 -#define JS_ERR_BINDING_PARAMETERS -2006 -#define JS_ERR_GENERAL_ERROR -2007 -#define JS_ERR_RESULTSET -2008 -#define JS_ERR_NO_WIDE_STATEMENTS -2009 +#define JS_ERR_INVALID_OBJECT -2001 +#define JS_ERR_INVALID_ARGUMENTS -2002 +#define JS_ERR_CONNECTION_ALREADY_EXISTS -2003 +#define JS_ERR_INITIALIZING_DBCAPI -2004 +#define JS_ERR_NOT_CONNECTED -2005 +#define JS_ERR_BINDING_PARAMETERS -2006 +#define JS_ERR_GENERAL_ERROR -2007 +#define JS_ERR_RESULTSET -2008 +#define JS_ERR_NO_WIDE_STATEMENTS -2009 diff --git a/src/h/nodever_cover.h b/src/h/nodever_cover.h index ea445dc..6b24d22 100644 --- a/src/h/nodever_cover.h +++ b/src/h/nodever_cover.h @@ -3,19 +3,4 @@ // *************************************************************************** #include -#if NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION == 10 -#define v010 1 -#define v012 0 -#elif NODE_MAJOR_VERSION == 0 && NODE_MINOR_VERSION == 12 -#define v010 0 -#define v012 1 -#else -#define v010 0 -#define v012 0 -#endif - -#if v010 -#define NODE_API_FUNC( name ) Handle name ( const Arguments &args ) -#else -#define NODE_API_FUNC( name ) void name ( const FunctionCallbackInfo &args ) -#endif +#define NODE_API_FUNC(name) void name(const FunctionCallbackInfo &args) diff --git a/src/h/sacapi.h b/src/h/sacapi.h index 1f8684e..e2b240e 100644 --- a/src/h/sacapi.h +++ b/src/h/sacapi.h @@ -21,7 +21,7 @@ // // *************************************************************************** -#ifndef SACAPI_H +#ifndef SACAPI_H #define SACAPI_H /** \mainpage SQL Anywhere C API @@ -85,122 +85,123 @@ * * You must define _SACAPI_VERSION as 1 or higher for this functionality. */ -#define SQLANY_API_VERSION_1 1 +#define SQLANY_API_VERSION_1 1 /** Version 2 introduced the "_ex" functions and the ability to cancel requests. * * You must define _SACAPI_VERSION as 2 or higher for this functionality. */ -#define SQLANY_API_VERSION_2 2 +#define SQLANY_API_VERSION_2 2 /** Version 3 introduced the "callback" function. * * You must define _SACAPI_VERSION as 3 or higher for this functionality. */ -#define SQLANY_API_VERSION_3 3 +#define SQLANY_API_VERSION_3 3 /** Version 4 introduced NCHAR support and wide inserts. * * You must define _SACAPI_VERSION as 4 or higher for this functionality. */ -#define SQLANY_API_VERSION_4 4 +#define SQLANY_API_VERSION_4 4 /** Version 5 introduced a way to reset sent data through sqlany_send_param_data() * and the A_FLOAT data type * * You must define _SACAPI_VERSION as 5 or higher for this functionality. */ -#define SQLANY_API_VERSION_5 5 +#define SQLANY_API_VERSION_5 5 /** If the command line does not specify which version to build, * then build the latest version. */ #ifndef _SACAPI_VERSION -#define _SACAPI_VERSION SQLANY_API_VERSION_5 +#define _SACAPI_VERSION SQLANY_API_VERSION_5 #endif /** Returns the minimal error buffer size. */ -#define SACAPI_ERROR_SIZE 256 +#define SACAPI_ERROR_SIZE 256 #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif -/** A handle to an interface context + /** A handle to an interface context */ -typedef struct a_sqlany_interface_context a_sqlany_interface_context; + typedef struct a_sqlany_interface_context a_sqlany_interface_context; -/** A handle to a connection object + /** A handle to a connection object */ -typedef struct a_sqlany_connection a_sqlany_connection; + typedef struct a_sqlany_connection a_sqlany_connection; -/** A handle to a statement object + /** A handle to a statement object */ -typedef struct a_sqlany_stmt a_sqlany_stmt; + typedef struct a_sqlany_stmt a_sqlany_stmt; -/** A portable 32-bit signed value */ -typedef signed int sacapi_i32; -/** A portable 32-bit unsigned value */ -typedef unsigned int sacapi_u32; -/** A portable boolean value */ -typedef sacapi_i32 sacapi_bool; + /** A portable 32-bit signed value */ + typedef signed int sacapi_i32; + /** A portable 32-bit unsigned value */ + typedef unsigned int sacapi_u32; + /** A portable boolean value */ + typedef sacapi_i32 sacapi_bool; // TODO:Character set issues /** The run-time calling convention in use (Windows only). */ #ifdef _WIN32 - #define _sacapi_entry_ __stdcall +#define _sacapi_entry_ __stdcall #endif #ifndef _sacapi_entry_ - #define _sacapi_entry_ +#define _sacapi_entry_ #endif /** Callback function type */ -#define SQLANY_CALLBACK _sacapi_entry_ - -/** Parameter type for sqlany_register_callback function used to specify the address of the callback routine. - */ -typedef int (SQLANY_CALLBACK *SQLANY_CALLBACK_PARM)(); - -/** Specifies the data type being passed in or retrieved. - */ -typedef enum a_sqlany_data_type -{ - /// Invalid data type. - A_INVALID_TYPE, - /// Binary data. Binary data is treated as-is and no character set conversion is performed. - A_BINARY, - /// String data. The data where character set conversion is performed. - A_STRING, - /// Double data. Includes float values. - A_DOUBLE, - /// 64-bit integer. - A_VAL64, - /// 64-bit unsigned integer. - A_UVAL64, - /// 32-bit integer. - A_VAL32, - /// 32-bit unsigned integer. - A_UVAL32, - /// 16-bit integer. - A_VAL16, - /// 16-bit unsigned integer. - A_UVAL16, - /// 8-bit integer. - A_VAL8, - /// 8-bit unsigned integer. - A_UVAL8 -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_5 - , - //// Float precision data. - A_FLOAT +#define SQLANY_CALLBACK _sacapi_entry_ + + /** Parameter type for sqlany_register_callback function used to specify the address of the callback routine. + */ + typedef int(SQLANY_CALLBACK *SQLANY_CALLBACK_PARM)(); + + /** Specifies the data type being passed in or retrieved. + */ + typedef enum a_sqlany_data_type + { + /// Invalid data type. + A_INVALID_TYPE, + /// Binary data. Binary data is treated as-is and no character set conversion is performed. + A_BINARY, + /// String data. The data where character set conversion is performed. + A_STRING, + /// Double data. Includes float values. + A_DOUBLE, + /// 64-bit integer. + A_VAL64, + /// 64-bit unsigned integer. + A_UVAL64, + /// 32-bit integer. + A_VAL32, + /// 32-bit unsigned integer. + A_UVAL32, + /// 16-bit integer. + A_VAL16, + /// 16-bit unsigned integer. + A_UVAL16, + /// 8-bit integer. + A_VAL8, + /// 8-bit unsigned integer. + A_UVAL8 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_5 + , + //// Float precision data. + A_FLOAT #endif -} a_sqlany_data_type; + } a_sqlany_data_type; -/** Returns a description of the attributes of a data value. + /** Returns a description of the attributes of a data value. * * To view examples of the a_sqlany_data_value structure in use, * see any of the following sample files in the sdk\\dbcapi\\examples directory @@ -213,39 +214,39 @@ typedef enum a_sqlany_data_type *
  • preparing_statements.cpp * */ -typedef struct a_sqlany_data_value -{ - /// A pointer to user supplied buffer of data. - char * buffer; - /// The size of the buffer. - size_t buffer_size; - /// A pointer to the number of valid bytes in the buffer. This value must be less than buffer_size. - size_t * length; - /// The type of the data - a_sqlany_data_type type; - /// A pointer to indicate whether the last fetched data is NULL. - sacapi_bool * is_null; -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_4 - /// Indicates whether the buffer value is an pointer to the actual value. - sacapi_bool is_address; + typedef struct a_sqlany_data_value + { + /// A pointer to user supplied buffer of data. + char *buffer; + /// The size of the buffer. + size_t buffer_size; + /// A pointer to the number of valid bytes in the buffer. This value must be less than buffer_size. + size_t *length; + /// The type of the data + a_sqlany_data_type type; + /// A pointer to indicate whether the last fetched data is NULL. + sacapi_bool *is_null; +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_4 + /// Indicates whether the buffer value is an pointer to the actual value. + sacapi_bool is_address; #endif -} a_sqlany_data_value; + } a_sqlany_data_value; -/** A data direction enumeration. + /** A data direction enumeration. */ -typedef enum a_sqlany_data_direction -{ - /// Invalid data direction. - DD_INVALID = 0x0, - /// Input-only host variables. - DD_INPUT = 0x1, - /// Output-only host variables. - DD_OUTPUT = 0x2, - /// Input and output host variables. - DD_INPUT_OUTPUT = 0x3 -} a_sqlany_data_direction; - -/** A bind parameter structure used to bind parameter and prepared statements. + typedef enum a_sqlany_data_direction + { + /// Invalid data direction. + DD_INVALID = 0x0, + /// Input-only host variables. + DD_INPUT = 0x1, + /// Output-only host variables. + DD_OUTPUT = 0x2, + /// Input and output host variables. + DD_INPUT_OUTPUT = 0x3 + } a_sqlany_data_direction; + + /** A bind parameter structure used to bind parameter and prepared statements. * * To view examples of the a_sqlany_bind_param structure in use, * see any of the following sample files in the sdk\\dbcapi\\examples directory @@ -258,78 +259,78 @@ typedef enum a_sqlany_data_direction * * \sa sqlany_execute() */ -typedef struct a_sqlany_bind_param -{ - /// The direction of the data. (input, output, input_output) - a_sqlany_data_direction direction; - /// The actual value of the data. - a_sqlany_data_value value; - /// Name of the bind parameter. This is only used by sqlany_describe_bind_param(). - char *name; -} a_sqlany_bind_param; + typedef struct a_sqlany_bind_param + { + /// The direction of the data. (input, output, input_output) + a_sqlany_data_direction direction; + /// The actual value of the data. + a_sqlany_data_value value; + /// Name of the bind parameter. This is only used by sqlany_describe_bind_param(). + char *name; + } a_sqlany_bind_param; -/** An enumeration of the native types of values as described by the server. + /** An enumeration of the native types of values as described by the server. * * The value types correspond to the embedded SQL data types. * * \hideinitializers * \sa sqlany_get_column_info(), a_sqlany_column_info */ -typedef enum a_sqlany_native_type -{ - /// No data type. - DT_NOTYPE = 0, - /// Null-terminated character string that is a valid date. - DT_DATE = 384, - /// Null-terminated character string that is a valid time. - DT_TIME = 388, - /// Null-terminated character string that is a valid timestamp. - DT_TIMESTAMP = 392, - /// Varying length character string, in the CHAR character set, with a two-byte length field. The maximum length is 32765 bytes. When sending data, you must set the length field. When fetching data, the database server sets the length field. The data is not null-terminated or blank-padded. - DT_VARCHAR = 448, - /// Fixed-length blank-padded character string, in the CHAR character set. The maximum length, specified in bytes, is 32767. The data is not null-terminated. - DT_FIXCHAR = 452, - /// Long varying length character string, in the CHAR character set. - DT_LONGVARCHAR = 456, - /// Null-terminated character string, in the CHAR character set. The string is blank-padded if the database is initialized with blank-padded strings. - DT_STRING = 460, - /// 8-byte floating-point number. - DT_DOUBLE = 480, - /// 4-byte floating-point number. - DT_FLOAT = 482, - /// Packed decimal number (proprietary format). - DT_DECIMAL = 484, - /// 32-bit signed integer. - DT_INT = 496, - /// 16-bit signed integer. - DT_SMALLINT = 500, - /// Varying length binary data with a two-byte length field. The maximum length is 32765 bytes. When supplying information to the database server, you must set the length field. When fetching information from the database server, the server sets the length field. - DT_BINARY = 524, - /// Long binary data. - DT_LONGBINARY = 528, - /// 8-bit signed integer. - DT_TINYINT = 604, - /// 64-bit signed integer. - DT_BIGINT = 608, - /// 32-bit unsigned integer. - DT_UNSINT = 612, - /// 16-bit unsigned integer. - DT_UNSSMALLINT = 616, - /// 64-bit unsigned integer. - DT_UNSBIGINT = 620, - /// 8-bit signed integer. - DT_BIT = 624, - /// Null-terminated character string, in the NCHAR character set. The string is blank-padded if the database is initialized with blank-padded strings. - DT_NSTRING = 628, - /// Fixed-length blank-padded character string, in the NCHAR character set. The maximum length, specified in bytes, is 32767. The data is not null-terminated. - DT_NFIXCHAR = 632, - /// Varying length character string, in the NCHAR character set, with a two-byte length field. The maximum length is 32765 bytes. When sending data, you must set the length field. When fetching data, the database server sets the length field. The data is not null-terminated or blank-padded. - DT_NVARCHAR = 636, - /// Long varying length character string, in the NCHAR character set. - DT_LONGNVARCHAR = 640 -} a_sqlany_native_type; - -/** Returns column metadata information. + typedef enum a_sqlany_native_type + { + /// No data type. + DT_NOTYPE = 0, + /// Null-terminated character string that is a valid date. + DT_DATE = 384, + /// Null-terminated character string that is a valid time. + DT_TIME = 388, + /// Null-terminated character string that is a valid timestamp. + DT_TIMESTAMP = 392, + /// Varying length character string, in the CHAR character set, with a two-byte length field. The maximum length is 32765 bytes. When sending data, you must set the length field. When fetching data, the database server sets the length field. The data is not null-terminated or blank-padded. + DT_VARCHAR = 448, + /// Fixed-length blank-padded character string, in the CHAR character set. The maximum length, specified in bytes, is 32767. The data is not null-terminated. + DT_FIXCHAR = 452, + /// Long varying length character string, in the CHAR character set. + DT_LONGVARCHAR = 456, + /// Null-terminated character string, in the CHAR character set. The string is blank-padded if the database is initialized with blank-padded strings. + DT_STRING = 460, + /// 8-byte floating-point number. + DT_DOUBLE = 480, + /// 4-byte floating-point number. + DT_FLOAT = 482, + /// Packed decimal number (proprietary format). + DT_DECIMAL = 484, + /// 32-bit signed integer. + DT_INT = 496, + /// 16-bit signed integer. + DT_SMALLINT = 500, + /// Varying length binary data with a two-byte length field. The maximum length is 32765 bytes. When supplying information to the database server, you must set the length field. When fetching information from the database server, the server sets the length field. + DT_BINARY = 524, + /// Long binary data. + DT_LONGBINARY = 528, + /// 8-bit signed integer. + DT_TINYINT = 604, + /// 64-bit signed integer. + DT_BIGINT = 608, + /// 32-bit unsigned integer. + DT_UNSINT = 612, + /// 16-bit unsigned integer. + DT_UNSSMALLINT = 616, + /// 64-bit unsigned integer. + DT_UNSBIGINT = 620, + /// 8-bit signed integer. + DT_BIT = 624, + /// Null-terminated character string, in the NCHAR character set. The string is blank-padded if the database is initialized with blank-padded strings. + DT_NSTRING = 628, + /// Fixed-length blank-padded character string, in the NCHAR character set. The maximum length, specified in bytes, is 32767. The data is not null-terminated. + DT_NFIXCHAR = 632, + /// Varying length character string, in the NCHAR character set, with a two-byte length field. The maximum length is 32765 bytes. When sending data, you must set the length field. When fetching data, the database server sets the length field. The data is not null-terminated or blank-padded. + DT_NVARCHAR = 636, + /// Long varying length character string, in the NCHAR character set. + DT_LONGNVARCHAR = 640 + } a_sqlany_native_type; + + /** Returns column metadata information. * * sqlany_get_column_info() can be used to populate this structure. * @@ -341,38 +342,38 @@ typedef enum a_sqlany_native_type *
  • dbcapi_isql.cpp * */ -typedef struct a_sqlany_column_info -{ - /// The name of the column (null-terminated). - /// The string can be referenced as long as the result set object is not freed. - char * name; - /// The column data type. - a_sqlany_data_type type; - /// The native type of the column in the database. - a_sqlany_native_type native_type; - /// The precision. - unsigned short precision; - /// The scale. - unsigned short scale; - /// The maximum size a data value in this column can take. - size_t max_size; - /// Indicates whether a value in the column can be null. - sacapi_bool nullable; -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_4 - /// The name of the table (null-terminated). - /// The string can be referenced as long as the result set object is not freed. - char * table_name; - /// The name of the owner (null-terminated). - /// The string can be referenced as long as the result set object is not freed. - char * owner_name; - /// Indicates whether the column is bound to a user buffer. - sacapi_bool is_bound; - /// Information about the bound column. - a_sqlany_data_value binding; + typedef struct a_sqlany_column_info + { + /// The name of the column (null-terminated). + /// The string can be referenced as long as the result set object is not freed. + char *name; + /// The column data type. + a_sqlany_data_type type; + /// The native type of the column in the database. + a_sqlany_native_type native_type; + /// The precision. + unsigned short precision; + /// The scale. + unsigned short scale; + /// The maximum size a data value in this column can take. + size_t max_size; + /// Indicates whether a value in the column can be null. + sacapi_bool nullable; +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_4 + /// The name of the table (null-terminated). + /// The string can be referenced as long as the result set object is not freed. + char *table_name; + /// The name of the owner (null-terminated). + /// The string can be referenced as long as the result set object is not freed. + char *owner_name; + /// Indicates whether the column is bound to a user buffer. + sacapi_bool is_bound; + /// Information about the bound column. + a_sqlany_data_value binding; #endif -} a_sqlany_column_info; + } a_sqlany_column_info; -/** Gets information about the currently bound parameters. + /** Gets information about the currently bound parameters. * * sqlany_get_bind_param_info() can be used to populate this structure. * @@ -387,30 +388,30 @@ typedef struct a_sqlany_column_info * * \sa sqlany_execute() */ -typedef struct a_sqlany_bind_param_info -{ - /// A pointer to the name of the parameter. - char * name; - /// The direction of the parameter. - a_sqlany_data_direction direction; - /// Information about the bound input value. - a_sqlany_data_value input_value; - /// Information about the bound output value. - a_sqlany_data_value output_value; - -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_4 - /// The native type of the column in the database. - a_sqlany_native_type native_type; - /// The precision. - unsigned short precision; - /// The scale. - unsigned short scale; - /// The maximum size a data value in this column can take. - size_t max_size; + typedef struct a_sqlany_bind_param_info + { + /// A pointer to the name of the parameter. + char *name; + /// The direction of the parameter. + a_sqlany_data_direction direction; + /// Information about the bound input value. + a_sqlany_data_value input_value; + /// Information about the bound output value. + a_sqlany_data_value output_value; + +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_4 + /// The native type of the column in the database. + a_sqlany_native_type native_type; + /// The precision. + unsigned short precision; + /// The scale. + unsigned short scale; + /// The maximum size a data value in this column can take. + size_t max_size; #endif -} a_sqlany_bind_param_info; + } a_sqlany_bind_param_info; -/** Returns metadata information about a column value in a result set. + /** Returns metadata information about a column value in a result set. * * sqlany_get_data_info() can be used * to populate this structure with information about what was last retrieved by a fetch operation. @@ -424,74 +425,76 @@ typedef struct a_sqlany_bind_param_info * * \sa sqlany_get_data_info() */ -typedef struct a_sqlany_data_info -{ - /// The type of the data in the column. - a_sqlany_data_type type; - /// Indicates whether the last fetched data is NULL. - /// This field is only valid after a successful fetch operation. - sacapi_bool is_null; - /// The total number of bytes available to be fetched. - /// This field is only valid after a successful fetch operation. - size_t data_size; -} a_sqlany_data_info; - -/** An enumeration of the callback types. + typedef struct a_sqlany_data_info + { + /// The type of the data in the column. + a_sqlany_data_type type; + /// Indicates whether the last fetched data is NULL. + /// This field is only valid after a successful fetch operation. + sacapi_bool is_null; + /// The total number of bytes available to be fetched. + /// This field is only valid after a successful fetch operation. + size_t data_size; + } a_sqlany_data_info; + + /** An enumeration of the callback types. * * The callback types correspond to the embedded SQL callback types. * * \hideinitializers * \sa sqlany_register_callback() */ -typedef enum a_sqlany_callback_type { - /// This function is called just before a database request is sent to the server. - /// CALLBACK_START is used only on Windows operating systems. - CALLBACK_START = 0, - /// This function is called repeatedly by the interface library while the database server or client library is busy processing your database request. - CALLBACK_WAIT, - /// This function is called after the response to a database request has been received by the DBLIB interface DLL. - /// CALLBACK_FINISH is used only on Windows operating systems. - CALLBACK_FINISH, - /// This function is called when messages are received from the server during the processing of a request. - /// Messages can be sent to the client application from the database server using the SQL MESSAGE statement. - /// Messages can also be generated by long running database server statements. - CALLBACK_MESSAGE = 7, - /// This function is called when the database server is about to drop a connection because of a liveness timeout, - /// through a DROP CONNECTION statement, or because the database server is being shut down. - /// The connection name conn_name is passed in to allow you to distinguish between connections. - /// If the connection was not named, it has a value of NULL. - CALLBACK_CONN_DROPPED, - /// This function is called once for each debug message and is passed a null-terminated string containing the text of the debug message. - /// A debug message is a message that is logged to the LogFile file. In order for a debug message to be passed to this callback, the LogFile - /// connection parameter must be used. The string normally has a newline character (\n) immediately before the terminating null character. - CALLBACK_DEBUG_MESSAGE, - /// This function is called when a file transfer requires validation. - /// If the client data transfer is being requested during the execution of indirect statements such as from within a stored procedure, - /// the client library will not allow a transfer unless the client application has registered a validation callback and the response from - /// the callback indicates that the transfer may take place. - CALLBACK_VALIDATE_FILE_TRANSFER -} a_sqlany_callback_type; - -/** An enumeration of the message types for the MESSAGE callback. + typedef enum a_sqlany_callback_type + { + /// This function is called just before a database request is sent to the server. + /// CALLBACK_START is used only on Windows operating systems. + CALLBACK_START = 0, + /// This function is called repeatedly by the interface library while the database server or client library is busy processing your database request. + CALLBACK_WAIT, + /// This function is called after the response to a database request has been received by the DBLIB interface DLL. + /// CALLBACK_FINISH is used only on Windows operating systems. + CALLBACK_FINISH, + /// This function is called when messages are received from the server during the processing of a request. + /// Messages can be sent to the client application from the database server using the SQL MESSAGE statement. + /// Messages can also be generated by long running database server statements. + CALLBACK_MESSAGE = 7, + /// This function is called when the database server is about to drop a connection because of a liveness timeout, + /// through a DROP CONNECTION statement, or because the database server is being shut down. + /// The connection name conn_name is passed in to allow you to distinguish between connections. + /// If the connection was not named, it has a value of NULL. + CALLBACK_CONN_DROPPED, + /// This function is called once for each debug message and is passed a null-terminated string containing the text of the debug message. + /// A debug message is a message that is logged to the LogFile file. In order for a debug message to be passed to this callback, the LogFile + /// connection parameter must be used. The string normally has a newline character (\n) immediately before the terminating null character. + CALLBACK_DEBUG_MESSAGE, + /// This function is called when a file transfer requires validation. + /// If the client data transfer is being requested during the execution of indirect statements such as from within a stored procedure, + /// the client library will not allow a transfer unless the client application has registered a validation callback and the response from + /// the callback indicates that the transfer may take place. + CALLBACK_VALIDATE_FILE_TRANSFER + } a_sqlany_callback_type; + + /** An enumeration of the message types for the MESSAGE callback. * * \hideinitializers * \sa sqlany_register_callback() */ -typedef enum a_sqlany_message_type { - /// The message type was INFO. - MESSAGE_TYPE_INFO = 0, - /// The message type was WARNING. - MESSAGE_TYPE_WARNING, - /// The message type was ACTION. - MESSAGE_TYPE_ACTION, - /// The message type was STATUS. - MESSAGE_TYPE_STATUS, - /// The message type was PROGRESS. - /// This type of message is generated by long running database server statements such as BACKUP DATABASE and LOAD TABLE. - MESSAGE_TYPE_PROGRESS -} a_sqlany_message_type; - -/** Initializes the interface. + typedef enum a_sqlany_message_type + { + /// The message type was INFO. + MESSAGE_TYPE_INFO = 0, + /// The message type was WARNING. + MESSAGE_TYPE_WARNING, + /// The message type was ACTION. + MESSAGE_TYPE_ACTION, + /// The message type was STATUS. + MESSAGE_TYPE_STATUS, + /// The message type was PROGRESS. + /// This type of message is generated by long running database server statements such as BACKUP DATABASE and LOAD TABLE. + MESSAGE_TYPE_PROGRESS + } a_sqlany_message_type; + + /** Initializes the interface. * * The following example demonstrates how to initialize the SQL Anywhere C API DLL: * @@ -510,9 +513,9 @@ typedef enum a_sqlany_message_type { * \return 1 on success, 0 otherwise * \sa sqlany_fini() */ -sacapi_bool sqlany_init( const char * app_name, sacapi_u32 api_version, sacapi_u32 * version_available ); + sacapi_bool sqlany_init(const char *app_name, sacapi_u32 api_version, sacapi_u32 *version_available); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_2 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_2 /** Initializes the interface using a context. * * \param app_name A string that names the API used, for example "PHP", "PERL", or "RUBY". @@ -522,26 +525,26 @@ sacapi_bool sqlany_init( const char * app_name, sacapi_u32 api_version, sacapi_u * \return a context object on success and NULL on failure. * \sa sqlany_fini_ex() */ - a_sqlany_interface_context *sqlany_init_ex( const char * app_name, sacapi_u32 api_version, sacapi_u32 * version_available ); + a_sqlany_interface_context *sqlany_init_ex(const char *app_name, sacapi_u32 api_version, sacapi_u32 *version_available); #endif -/** Finalizes the interface. + /** Finalizes the interface. * * Frees any resources allocated by the API. * * \sa sqlany_init() */ -void sqlany_fini(); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_2 + void sqlany_fini(); +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_2 /** Finalize the interface that was created using the specified context. * Frees any resources allocated by the API. * \param context A context object that was returned from sqlany_init_ex() * \sa sqlany_init_ex() */ - void sqlany_fini_ex( a_sqlany_interface_context *context ); + void sqlany_fini_ex(a_sqlany_interface_context *context); #endif -/** Creates a connection object. + /** Creates a connection object. * * You must create an API connection object before establishing a database connection. Errors can be retrieved * from the connection object. Only one request can be processed on a connection at a time. In addition, @@ -551,8 +554,8 @@ void sqlany_fini(); * \return A connection object * \sa sqlany_connect(), sqlany_disconnect() */ -a_sqlany_connection * sqlany_new_connection( void ); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_2 + a_sqlany_connection *sqlany_new_connection(void); +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_2 /** Creates a connection object using a context. * An API connection object needs to be created before a database connection is established. Errors can be retrieved * from the connection object. Only one request can be processed on a connection at a time. In addition, @@ -562,34 +565,34 @@ a_sqlany_connection * sqlany_new_connection( void ); * \return A connection object * \sa sqlany_connect(), sqlany_disconnect(), sqlany_init_ex() */ - a_sqlany_connection *sqlany_new_connection_ex( a_sqlany_interface_context *context ); + a_sqlany_connection *sqlany_new_connection_ex(a_sqlany_interface_context *context); #endif -/** Frees the resources associated with a connection object. + /** Frees the resources associated with a connection object. * * \param sqlany_conn A connection object created with sqlany_new_connection(). * \sa sqlany_new_connection() */ -void sqlany_free_connection( a_sqlany_connection *sqlany_conn ); + void sqlany_free_connection(a_sqlany_connection *sqlany_conn); -/** Creates a connection object based on a supplied DBLIB SQLCA pointer. + /** Creates a connection object based on a supplied DBLIB SQLCA pointer. * * \param arg A void * pointer to a DBLIB SQLCA object. * \return A connection object. * \sa sqlany_new_connection(), sqlany_execute(), sqlany_execute_direct(), sqlany_execute_immediate(), sqlany_prepare() */ -a_sqlany_connection * sqlany_make_connection( void * arg ); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_2 + a_sqlany_connection *sqlany_make_connection(void *arg); +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_2 /** Creates a connection object based on a supplied DBLIB SQLCA pointer and context. * \param context A valid context object that was created by sqlany_init_ex() * \param arg A void * pointer to a DBLIB SQLCA object. * \return A connection object. * \sa sqlany_init_ex(), sqlany_execute(), sqlany_execute_direct(), sqlany_execute_immediate(), sqlany_prepare() */ - a_sqlany_connection *sqlany_make_connection_ex( a_sqlany_interface_context *context, void *arg ); + a_sqlany_connection *sqlany_make_connection_ex(a_sqlany_interface_context *context, void *arg); #endif -/** Creates a connection to a SQL Anywhere database server using the supplied connection object and connection string. + /** Creates a connection to a SQL Anywhere database server using the supplied connection object and connection string. * * The supplied connection object must first be allocated using sqlany_new_connection(). * @@ -616,9 +619,9 @@ a_sqlany_connection * sqlany_make_connection( void * arg ); * retrieve the error code and message. * \sa sqlany_new_connection(), sqlany_error() */ -sacapi_bool sqlany_connect( a_sqlany_connection * sqlany_conn, const char * str ); + sacapi_bool sqlany_connect(a_sqlany_connection *sqlany_conn, const char *str); -/** Disconnects an already established SQL Anywhere connection. + /** Disconnects an already established SQL Anywhere connection. * * All uncommitted transactions are rolled back. * @@ -626,17 +629,17 @@ sacapi_bool sqlany_connect( a_sqlany_connection * sqlany_conn, const char * str * \return 1 when successful or 0 when unsuccessful. * \sa sqlany_connect(), sqlany_new_connection() */ -sacapi_bool sqlany_disconnect( a_sqlany_connection * sqlany_conn ); + sacapi_bool sqlany_disconnect(a_sqlany_connection *sqlany_conn); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_2 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_2 /** Cancel an outstanding request on a connection. * This function can be used to cancel an outstanding request on a specific connection. * \param sqlany_conn A connection object with a connection established using sqlany_connect(). */ - void sqlany_cancel( a_sqlany_connection * sqlany_conn ); + void sqlany_cancel(a_sqlany_connection *sqlany_conn); #endif -/** Executes the supplied SQL statement immediately without returning a result set. + /** Executes the supplied SQL statement immediately without returning a result set. * * This function is useful for SQL statements that do not return a result set. * @@ -644,9 +647,9 @@ sacapi_bool sqlany_disconnect( a_sqlany_connection * sqlany_conn ); * \param sql A string representing the SQL statement to be executed. * \return 1 on success or 0 on failure. */ -sacapi_bool sqlany_execute_immediate( a_sqlany_connection * sqlany_conn, const char * sql ); + sacapi_bool sqlany_execute_immediate(a_sqlany_connection *sqlany_conn, const char *sql); -/** Prepares a supplied SQL string. + /** Prepares a supplied SQL string. * * Execution does not happen until sqlany_execute() is * called. The returned statement object should be freed using sqlany_free_stmt(). @@ -670,24 +673,24 @@ sacapi_bool sqlany_execute_immediate( a_sqlany_connection * sqlany_conn, const c * to execute the statement. * \sa sqlany_free_stmt(), sqlany_connect(), sqlany_execute(), sqlany_num_params(), sqlany_describe_bind_param(), sqlany_bind_param() */ -a_sqlany_stmt * sqlany_prepare( a_sqlany_connection * sqlany_conn, const char * sql_str ); + a_sqlany_stmt *sqlany_prepare(a_sqlany_connection *sqlany_conn, const char *sql_str); -/** Frees resources associated with a prepared statement object. + /** Frees resources associated with a prepared statement object. * * \param sqlany_stmt A statement object returned by the successful execution of sqlany_prepare() or sqlany_execute_direct(). * \sa sqlany_prepare(), sqlany_execute_direct() */ -void sqlany_free_stmt( a_sqlany_stmt * sqlany_stmt ); + void sqlany_free_stmt(a_sqlany_stmt *sqlany_stmt); -/** Returns the number of parameters expected for a prepared statement. + /** Returns the number of parameters expected for a prepared statement. * * \param sqlany_stmt A statement object returned by the successful execution of sqlany_prepare(). * \return The expected number of parameters, or -1 if the statement object is not valid. * \sa sqlany_prepare() */ -sacapi_i32 sqlany_num_params( a_sqlany_stmt * sqlany_stmt ); + sacapi_i32 sqlany_num_params(a_sqlany_stmt *sqlany_stmt); -/** Describes the bind parameters of a prepared statement. + /** Describes the bind parameters of a prepared statement. * * This function allows the caller to determine information about prepared statement parameters. The type of prepared * statement, stored procedured or a DML, determines the amount of information provided. The direction of the parameters @@ -699,9 +702,9 @@ sacapi_i32 sqlany_num_params( a_sqlany_stmt * sqlany_stmt ); * \return 1 when successful or 0 when unsuccessful. * \sa sqlany_bind_param(), sqlany_prepare() */ -sacapi_bool sqlany_describe_bind_param( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param * param ); + sacapi_bool sqlany_describe_bind_param(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param *param); -/** Bind a user-supplied buffer as a parameter to the prepared statement. + /** Bind a user-supplied buffer as a parameter to the prepared statement. * * \param sqlany_stmt A statement prepared successfully using sqlany_prepare(). * \param index The index of the parameter. This number must be between 0 and sqlany_num_params() - 1. @@ -709,9 +712,9 @@ sacapi_bool sqlany_describe_bind_param( a_sqlany_stmt * sqlany_stmt, sacapi_u32 * \return 1 on success or 0 on unsuccessful. * \sa sqlany_describe_bind_param() */ -sacapi_bool sqlany_bind_param( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param * param ); + sacapi_bool sqlany_bind_param(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param *param); -/** Sends data as part of a bound parameter. + /** Sends data as part of a bound parameter. * * This method can be used to send a large amount of data for a bound parameter in chunks. * This method can be used only when the batch size is 1. @@ -723,10 +726,9 @@ sacapi_bool sqlany_bind_param( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, a_ * \return 1 on success or 0 on failure. * \sa sqlany_prepare() */ -sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, char * buffer, size_t size ); - + sacapi_bool sqlany_send_param_data(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, char *buffer, size_t size); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_5 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_5 /** Clears param data that was previously been set using \sa sqlany_send_param_data() * * This method can be used to clear data that was previously been sent using sqlany_send_param_data() @@ -737,7 +739,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return 1 on success or 0 on failure * \sa sqlany_prepare(), sqlany_send_param_data() */ - sacapi_bool sqlany_reset_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index ); + sacapi_bool sqlany_reset_param_data(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index); /** Retrieves the length of the last error message stored in the connection object * including the NULL terminator. If there is no error, 0 is returned. @@ -745,10 +747,10 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \param sqlany_conn A connection object returned from sqlany_new_connection(). * \return The length of the last error message including the NULL terminator. */ - size_t sqlany_error_length( a_sqlany_connection * sqlany_conn ); + size_t sqlany_error_length(a_sqlany_connection *sqlany_conn); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_4 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_4 /** Sets the size of the row array for a batch execute. * * The batch size is used only for an INSERT statement. The default batch size is 1. @@ -759,7 +761,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return 1 on success or 0 on failure. * \sa sqlany_bind_param(), sqlany_get_batch_size() */ - sacapi_bool sqlany_set_batch_size( a_sqlany_stmt * sqlany_stmt, sacapi_u32 num_rows ); + sacapi_bool sqlany_set_batch_size(a_sqlany_stmt *sqlany_stmt, sacapi_u32 num_rows); /** Sets the bind type of parameters. * @@ -778,7 +780,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return 1 on success or 0 on failure. * \sa sqlany_bind_param() */ - sacapi_bool sqlany_set_param_bind_type( a_sqlany_stmt * sqlany_stmt, size_t row_size ); + sacapi_bool sqlany_set_param_bind_type(a_sqlany_stmt *sqlany_stmt, size_t row_size); /** Retrieves the size of the row array for a batch execute. * @@ -786,7 +788,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return The size of the row array. * \sa sqlany_set_batch_size() */ - sacapi_u32 sqlany_get_batch_size( a_sqlany_stmt * sqlany_stmt ); + sacapi_u32 sqlany_get_batch_size(a_sqlany_stmt *sqlany_stmt); /** Sets the size of the row set to be fetched by the sqlany_fetch_absolute() and sqlany_fetch_next() functions. * @@ -797,7 +799,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return 1 on success or 0 on failure. * \sa sqlany_bind_column(), sqlany_fetch_absolute(), sqlany_fetch_next(), sqlany_get_rowset_size() */ - sacapi_bool sqlany_set_rowset_size( a_sqlany_stmt * sqlany_stmt, sacapi_u32 num_rows ); + sacapi_bool sqlany_set_rowset_size(a_sqlany_stmt *sqlany_stmt, sacapi_u32 num_rows); /** Retrieves the size of the row set to be fetched by the sqlany_fetch_absolute() and sqlany_fetch_next() functions. * @@ -805,7 +807,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return The size of the row set, or 0 if the statement does not return a result set. * \sa sqlany_set_rowset_size(), sqlany_fetch_absolute(), sqlany_fetch_next() */ - sacapi_u32 sqlany_get_rowset_size( a_sqlany_stmt * sqlany_stmt ); + sacapi_u32 sqlany_get_rowset_size(a_sqlany_stmt *sqlany_stmt); /** Sets the bind type of columns. * @@ -824,7 +826,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return 1 on success or 0 on failure. * \sa sqlany_bind_column() */ - sacapi_bool sqlany_set_column_bind_type( a_sqlany_stmt * sqlany_stmt, sacapi_u32 row_size ); + sacapi_bool sqlany_set_column_bind_type(a_sqlany_stmt *sqlany_stmt, sacapi_u32 row_size); /** Binds a user-supplied buffer as a result set column to the prepared statement. * @@ -838,7 +840,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return 1 on success or 0 on unsuccessful. * \sa sqlany_clear_column_bindings(), sqlany_set_rowset_size() */ - sacapi_bool sqlany_bind_column( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, a_sqlany_data_value * value ); + sacapi_bool sqlany_bind_column(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, a_sqlany_data_value *value); /** Removes all column bindings defined using sqlany_bind_column(). * @@ -846,7 +848,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return 1 on success or 0 on failure. * \sa sqlany_bind_column() */ - sacapi_bool sqlany_clear_column_bindings( a_sqlany_stmt * sqlany_stmt ); + sacapi_bool sqlany_clear_column_bindings(a_sqlany_stmt *sqlany_stmt); /** Returns the number of rows fetched. * @@ -860,7 +862,7 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return The number of rows fetched or -1 on failure. * \sa sqlany_bind_column(), sqlany_fetch_next(), sqlany_fetch_absolute() */ - sacapi_i32 sqlany_fetched_rows( a_sqlany_stmt * sqlany_stmt ); + sacapi_i32 sqlany_fetched_rows(a_sqlany_stmt *sqlany_stmt); /** Sets the current row in the fetched row set. * @@ -874,18 +876,18 @@ sacapi_bool sqlany_send_param_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 inde * \return 1 on success or 0 on failure. * \sa sqlany_set_rowset_size(), sqlany_get_column(), sqlany_get_data(), sqlany_get_data_info(), sqlany_fetch_absolute(), sqlany_fetch_next() */ - sacapi_bool sqlany_set_rowset_pos( a_sqlany_stmt * sqlany_stmt, sacapi_u32 row_num ); + sacapi_bool sqlany_set_rowset_pos(a_sqlany_stmt *sqlany_stmt, sacapi_u32 row_num); #endif -/** Resets a statement to its prepared state condition. + /** Resets a statement to its prepared state condition. * * \param sqlany_stmt A statement prepared successfully using sqlany_prepare(). * \return 1 on success, 0 on failure. * \sa sqlany_prepare() */ -sacapi_bool sqlany_reset( a_sqlany_stmt * sqlany_stmt ); + sacapi_bool sqlany_reset(a_sqlany_stmt *sqlany_stmt); -/** Retrieves information about the parameters that were bound using sqlany_bind_param(). + /** Retrieves information about the parameters that were bound using sqlany_bind_param(). * * \param sqlany_stmt A statement prepared successfully using sqlany_prepare(). * \param index The index of the parameter. This number should be between 0 and sqlany_num_params() - 1. @@ -893,9 +895,9 @@ sacapi_bool sqlany_reset( a_sqlany_stmt * sqlany_stmt ); * \return 1 on success or 0 on failure. * \sa sqlany_bind_param(), sqlany_describe_bind_param(), sqlany_prepare() */ -sacapi_bool sqlany_get_bind_param_info( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param_info * info ); + sacapi_bool sqlany_get_bind_param_info(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param_info *info); -/** Executes a prepared statement. + /** Executes a prepared statement. * * You can use sqlany_num_cols() to verify if the executed statement returned a result set. * @@ -931,9 +933,9 @@ sacapi_bool sqlany_get_bind_param_info( a_sqlany_stmt * sqlany_stmt, sacapi_u32 * \return 1 if the statement is executed successfully or 0 on failure. * \sa sqlany_prepare() */ -sacapi_bool sqlany_execute( a_sqlany_stmt * sqlany_stmt ); + sacapi_bool sqlany_execute(a_sqlany_stmt *sqlany_stmt); -/** Executes the SQL statement specified by the string argument and possibly returns a result set. + /** Executes the SQL statement specified by the string argument and possibly returns a result set. * * Use this method to prepare and execute a statement, * or instead of calling sqlany_prepare() followed by sqlany_execute(). @@ -962,9 +964,9 @@ sacapi_bool sqlany_execute( a_sqlany_stmt * sqlany_stmt ); * \return A statement handle if the function executes successfully, NULL when the function executes unsuccessfully. * \sa sqlany_fetch_absolute(), sqlany_fetch_next(), sqlany_num_cols(), sqlany_get_column() */ -a_sqlany_stmt * sqlany_execute_direct( a_sqlany_connection * sqlany_conn, const char * sql_str ); + a_sqlany_stmt *sqlany_execute_direct(a_sqlany_connection *sqlany_conn, const char *sql_str); -/** Moves the current row in the result set to the specified row number and then fetches + /** Moves the current row in the result set to the specified row number and then fetches * rows of data starting from the current row. * * The number of rows fetched is set using the sqlany_set_rowset_size() function. By default, one row is returned. @@ -975,9 +977,9 @@ a_sqlany_stmt * sqlany_execute_direct( a_sqlany_connection * sqlany_conn, const * \return 1 if the fetch was successfully, 0 when the fetch is unsuccessful. * \sa sqlany_execute_direct(), sqlany_execute(), sqlany_error(), sqlany_fetch_next(), sqlany_set_rowset_size() */ -sacapi_bool sqlany_fetch_absolute( a_sqlany_stmt * sqlany_stmt, sacapi_i32 row_num ); + sacapi_bool sqlany_fetch_absolute(a_sqlany_stmt *sqlany_stmt, sacapi_i32 row_num); -/** Returns the next set of rows from the result set. + /** Returns the next set of rows from the result set. * * When the result object is first created, the current row * pointer is set to before the first row, that is, row 0. @@ -991,9 +993,9 @@ sacapi_bool sqlany_fetch_absolute( a_sqlany_stmt * sqlany_stmt, sacapi_i32 row_n * \return 1 if the fetch was successfully, 0 when the fetch is unsuccessful. * \sa sqlany_fetch_absolute(), sqlany_execute_direct(), sqlany_execute(), sqlany_error(), sqlany_set_rowset_size() */ -sacapi_bool sqlany_fetch_next( a_sqlany_stmt * sqlany_stmt ); + sacapi_bool sqlany_fetch_next(a_sqlany_stmt *sqlany_stmt); -/** Advances to the next result set in a multiple result set query. + /** Advances to the next result set in a multiple result set query. * * If a query (such as a call to a stored procedure) returns multiple result sets, then this function * advances from the current result set to the next. @@ -1017,26 +1019,26 @@ sacapi_bool sqlany_fetch_next( a_sqlany_stmt * sqlany_stmt ); * \return 1 if the statement successfully advances to the next result set, 0 otherwise. * \sa sqlany_execute_direct(), sqlany_execute() */ -sacapi_bool sqlany_get_next_result( a_sqlany_stmt * sqlany_stmt ); + sacapi_bool sqlany_get_next_result(a_sqlany_stmt *sqlany_stmt); -/** Returns the number of rows affected by execution of the prepared statement. + /** Returns the number of rows affected by execution of the prepared statement. * * \param sqlany_stmt A statement that was prepared and executed successfully with no result set returned. * For example, an INSERT, UPDATE or DELETE statement was executed. * \return The number of rows affected or -1 on failure. * \sa sqlany_execute(), sqlany_execute_direct() */ -sacapi_i32 sqlany_affected_rows( a_sqlany_stmt * sqlany_stmt ); + sacapi_i32 sqlany_affected_rows(a_sqlany_stmt *sqlany_stmt); -/** Returns number of columns in the result set. + /** Returns number of columns in the result set. * * \param sqlany_stmt A statement object created by sqlany_prepare() or sqlany_execute_direct(). * \return The number of columns in the result set or -1 on a failure. * \sa sqlany_execute(), sqlany_execute_direct(), sqlany_prepare() */ -sacapi_i32 sqlany_num_cols( a_sqlany_stmt * sqlany_stmt ); + sacapi_i32 sqlany_num_cols(a_sqlany_stmt *sqlany_stmt); -/** Returns the number of rows in the result set. + /** Returns the number of rows in the result set. * * By default this function only returns an estimate. To return an exact count, set the row_counts option * on the connection. @@ -1048,9 +1050,9 @@ sacapi_i32 sqlany_num_cols( a_sqlany_stmt * sqlany_stmt ); * if the number of rows is exact. * \sa sqlany_execute_direct(), sqlany_execute() */ -sacapi_i32 sqlany_num_rows( a_sqlany_stmt * sqlany_stmt ); + sacapi_i32 sqlany_num_rows(a_sqlany_stmt *sqlany_stmt); -/** Fills the supplied buffer with the value fetched for the specified column at the current row. + /** Fills the supplied buffer with the value fetched for the specified column at the current row. * * When a sqlany_fetch_absolute() or sqlany_fetch_next() function is executed, a row set * is created and the current row is set to be the first row in the row set. The current @@ -1078,9 +1080,9 @@ sacapi_i32 sqlany_num_rows( a_sqlany_stmt * sqlany_stmt ); * not enough memory to retrieve the full value from the SQL Anywhere database server. * \sa sqlany_execute_direct(), sqlany_execute(), sqlany_fetch_absolute(), sqlany_fetch_next(), sqlany_set_rowset_pos() */ -sacapi_bool sqlany_get_column( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_value * buffer ); + sacapi_bool sqlany_get_column(a_sqlany_stmt *sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_value *buffer); -/** Retrieves the data fetched for the specified column at the current row into the supplied buffer memory. + /** Retrieves the data fetched for the specified column at the current row into the supplied buffer memory. * * When a sqlany_fetch_absolute() or sqlany_fetch_next() function is executed, a row set * is created and the current row is set to be the first row in the row set. The current @@ -1100,9 +1102,9 @@ sacapi_bool sqlany_get_column( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index * 0 indicates that no data remains to be copied. -1 indicates a failure. * \sa sqlany_execute(), sqlany_execute_direct(), sqlany_fetch_absolute(), sqlany_fetch_next(), sqlany_set_rowset_pos() */ -sacapi_i32 sqlany_get_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index, size_t offset, void * buffer, size_t size ); + sacapi_i32 sqlany_get_data(a_sqlany_stmt *sqlany_stmt, sacapi_u32 col_index, size_t offset, void *buffer, size_t size); -/** Retrieves information about the fetched data at the current row. + /** Retrieves information about the fetched data at the current row. * * When a sqlany_fetch_absolute() or sqlany_fetch_next() function is executed, a row set * is created and the current row is set to be the first row in the row set. The current @@ -1115,9 +1117,9 @@ sacapi_i32 sqlany_get_data( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index, s * \return 1 on success, and 0 on failure. Failure is returned when any of the supplied parameters are invalid. * \sa sqlany_execute(), sqlany_execute_direct(), sqlany_fetch_absolute(), sqlany_fetch_next(), sqlany_set_rowset_pos() */ -sacapi_bool sqlany_get_data_info( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_info * buffer ); + sacapi_bool sqlany_get_data_info(a_sqlany_stmt *sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_info *buffer); -/** Retrieves column metadata information and fills the a_sqlany_column_info structure with information about the column. + /** Retrieves column metadata information and fills the a_sqlany_column_info structure with information about the column. * * \param sqlany_stmt A statement object created by sqlany_prepare() or sqlany_execute_direct(). * \param col_index The column number between 0 and sqlany_num_cols() - 1. @@ -1126,25 +1128,25 @@ sacapi_bool sqlany_get_data_info( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_in * or if the statement does not return a result set. * \sa sqlany_execute(), sqlany_execute_direct(), sqlany_prepare() */ -sacapi_bool sqlany_get_column_info( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index, a_sqlany_column_info * buffer ); + sacapi_bool sqlany_get_column_info(a_sqlany_stmt *sqlany_stmt, sacapi_u32 col_index, a_sqlany_column_info *buffer); -/** Commits the current transaction. + /** Commits the current transaction. * * \param sqlany_conn The connection object on which the commit operation is performed. * \return 1 when successful or 0 when unsuccessful. * \sa sqlany_rollback() */ -sacapi_bool sqlany_commit( a_sqlany_connection * sqlany_conn ); + sacapi_bool sqlany_commit(a_sqlany_connection *sqlany_conn); -/** Rolls back the current transaction. + /** Rolls back the current transaction. * * \param sqlany_conn The connection object on which the rollback operation is to be performed. * \return 1 on success, 0 otherwise. * \sa sqlany_commit() */ -sacapi_bool sqlany_rollback( a_sqlany_connection * sqlany_conn ); + sacapi_bool sqlany_rollback(a_sqlany_connection *sqlany_conn); -/** Returns the current client version. + /** Returns the current client version. * * This method fills the buffer passed with the major, minor, patch, and build number of the client library. * The buffer will be null-terminated. @@ -1153,8 +1155,8 @@ sacapi_bool sqlany_rollback( a_sqlany_connection * sqlany_conn ); * \param len The length of the buffer supplied. * \return 1 when successful or 0 when unsuccessful. */ -sacapi_bool sqlany_client_version( char * buffer, size_t len ); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_2 + sacapi_bool sqlany_client_version(char *buffer, size_t len); +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_2 /** Returns the current client version. * * This method fills the buffer passed with the major, minor, patch, and build number of the client library. @@ -1166,10 +1168,10 @@ sacapi_bool sqlany_client_version( char * buffer, size_t len ); * \return 1 when successful or 0 when unsuccessful. * \sa sqlany_init_ex() */ - sacapi_bool sqlany_client_version_ex( a_sqlany_interface_context *context, char *buffer, size_t len ); + sacapi_bool sqlany_client_version_ex(a_sqlany_interface_context *context, char *buffer, size_t len); #endif -/** Retrieves the last error code and message stored in the connection object. + /** Retrieves the last error code and message stored in the connection object. * * \param sqlany_conn A connection object returned from sqlany_new_connection(). * \param buffer A buffer to be filled with the error message. @@ -1177,9 +1179,9 @@ sacapi_bool sqlany_client_version( char * buffer, size_t len ); * \return The last error code. Positive values are warnings, negative values are errors, and 0 indicates success. * \sa sqlany_connect() */ -sacapi_i32 sqlany_error( a_sqlany_connection * sqlany_conn, char * buffer, size_t size ); + sacapi_i32 sqlany_error(a_sqlany_connection *sqlany_conn, char *buffer, size_t size); -/** Retrieves the current SQLSTATE. + /** Retrieves the current SQLSTATE. * * \param sqlany_conn A connection object returned from sqlany_new_connection(). * \param buffer A buffer to be filled with the current 5-character SQLSTATE. @@ -1187,16 +1189,16 @@ sacapi_i32 sqlany_error( a_sqlany_connection * sqlany_conn, char * buffer, size_ * \return The number of bytes copied into the buffer. * \sa sqlany_error() */ -size_t sqlany_sqlstate( a_sqlany_connection * sqlany_conn, char * buffer, size_t size ); + size_t sqlany_sqlstate(a_sqlany_connection *sqlany_conn, char *buffer, size_t size); -/** Clears the last stored error code + /** Clears the last stored error code * * \param sqlany_conn A connection object returned from sqlany_new_connection(). * \sa sqlany_new_connection() */ -void sqlany_clear_error( a_sqlany_connection * sqlany_conn ); + void sqlany_clear_error(a_sqlany_connection *sqlany_conn); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_3 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_3 /** Register a callback routine. * * This function can be used to register callback functions. @@ -1239,7 +1241,7 @@ void sqlany_clear_error( a_sqlany_connection * sqlany_conn ); * \param callback Address of the callback routine. * \return 1 when successful or 0 when unsuccessful. */ - sacapi_bool sqlany_register_callback( a_sqlany_connection * sqlany_conn, a_sqlany_callback_type index, SQLANY_CALLBACK_PARM callback ); + sacapi_bool sqlany_register_callback(a_sqlany_connection *sqlany_conn, a_sqlany_callback_type index, SQLANY_CALLBACK_PARM callback); #endif #if defined(__cplusplus) @@ -1278,4 +1280,4 @@ void sqlany_clear_error( a_sqlany_connection * sqlany_conn ); * This is an example of how to register and use a callback function. */ -#endif +#endif diff --git a/src/h/sacapidll.h b/src/h/sacapidll.h index 49ed504..eb73412 100644 --- a/src/h/sacapidll.h +++ b/src/h/sacapidll.h @@ -31,78 +31,78 @@ * The user will need to include sacapidll.h in their source files and compile in sacapidll.c */ - -#if defined( __cplusplus ) -extern "C" { +#if defined(__cplusplus) +extern "C" +{ #endif -typedef sacapi_bool (*sqlany_init_func)( const char * app_name, sacapi_u32 api_version, sacapi_u32 * max_version ); -typedef void (*sqlany_fini_func)(); -typedef a_sqlany_connection * (*sqlany_new_connection_func)( ); -typedef void (*sqlany_free_connection_func)( a_sqlany_connection *sqlany_conn ); -typedef a_sqlany_connection * (*sqlany_make_connection_func)( void * arg ); -typedef sacapi_bool (*sqlany_connect_func)( a_sqlany_connection * sqlany_conn, const char * str ); -typedef sacapi_bool (*sqlany_disconnect_func)( a_sqlany_connection * sqlany_conn ); -typedef sacapi_bool (*sqlany_execute_immediate_func)( a_sqlany_connection * sqlany_conn, const char * sql ); -typedef a_sqlany_stmt * (*sqlany_prepare_func)( a_sqlany_connection * sqlany_conn, const char * sql_str ); -typedef void (*sqlany_free_stmt_func)( a_sqlany_stmt * sqlany_stmt ); -typedef sacapi_i32 (*sqlany_num_params_func)( a_sqlany_stmt * sqlany_stmt ); -typedef sacapi_bool (*sqlany_describe_bind_param_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param * params ); -typedef sacapi_bool (*sqlany_bind_param_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param * params ); -typedef sacapi_bool (*sqlany_send_param_data_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, char * buffer, size_t size ); -typedef sacapi_bool (*sqlany_reset_func)( a_sqlany_stmt * sqlany_stmt ); -typedef sacapi_bool (*sqlany_get_bind_param_info_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param_info * info ); -typedef sacapi_bool (*sqlany_execute_func)( a_sqlany_stmt * sqlany_stmt ); -typedef a_sqlany_stmt * (*sqlany_execute_direct_func)( a_sqlany_connection * sqlany_conn, const char * sql_str ); -typedef sacapi_bool (*sqlany_fetch_absolute_func)( a_sqlany_stmt * sqlany_result, sacapi_i32 row_num ); -typedef sacapi_bool (*sqlany_fetch_next_func)( a_sqlany_stmt * sqlany_stmt ); -typedef sacapi_bool (*sqlany_get_next_result_func)( a_sqlany_stmt * sqlany_stmt ); -typedef sacapi_i32 (*sqlany_affected_rows_func)( a_sqlany_stmt * sqlany_stmt ); -typedef sacapi_i32 (*sqlany_num_cols_func)( a_sqlany_stmt * sqlany_stmt ); -typedef sacapi_i32 (*sqlany_num_rows_func)( a_sqlany_stmt * sqlany_stmt ); -typedef sacapi_bool (*sqlany_get_column_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_value * buffer ); -typedef sacapi_i32 (*sqlany_get_data_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index, size_t offset, void * buffer, size_t size ); -typedef sacapi_bool (*sqlany_get_data_info_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_info * buffer ); -typedef sacapi_bool (*sqlany_get_column_info_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 col_index, a_sqlany_column_info * buffer ); -typedef sacapi_bool (*sqlany_commit_func)( a_sqlany_connection * sqlany_conn ); -typedef sacapi_bool (*sqlany_rollback_func)( a_sqlany_connection * sqlany_conn ); -typedef sacapi_bool (*sqlany_client_version_func)( char * buffer, size_t len ); -typedef sacapi_i32 (*sqlany_error_func)( a_sqlany_connection * sqlany_conn, char * buffer, size_t size ); -typedef size_t (*sqlany_sqlstate_func)( a_sqlany_connection * sqlany_conn, char * buffer, size_t size ); -typedef void (*sqlany_clear_error_func)( a_sqlany_connection * sqlany_conn ); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_2 - typedef a_sqlany_interface_context *(*sqlany_init_ex_func)( const char *app_name, sacapi_u32 api_version, sacapi_u32 *max_version ); - typedef void (*sqlany_fini_ex_func)( a_sqlany_interface_context *context ); - typedef a_sqlany_connection *(*sqlany_new_connection_ex_func)( a_sqlany_interface_context *context ); - typedef a_sqlany_connection *(*sqlany_make_connection_ex_func)( a_sqlany_interface_context *context, void *arg ); - typedef sacapi_bool (*sqlany_client_version_ex_func)( a_sqlany_interface_context *context, char *buffer, size_t len ); - typedef void (*sqlany_cancel_func)( a_sqlany_connection * sqlany_conn ); + typedef sacapi_bool (*sqlany_init_func)(const char *app_name, sacapi_u32 api_version, sacapi_u32 *max_version); + typedef void (*sqlany_fini_func)(); + typedef a_sqlany_connection *(*sqlany_new_connection_func)(); + typedef void (*sqlany_free_connection_func)(a_sqlany_connection *sqlany_conn); + typedef a_sqlany_connection *(*sqlany_make_connection_func)(void *arg); + typedef sacapi_bool (*sqlany_connect_func)(a_sqlany_connection *sqlany_conn, const char *str); + typedef sacapi_bool (*sqlany_disconnect_func)(a_sqlany_connection *sqlany_conn); + typedef sacapi_bool (*sqlany_execute_immediate_func)(a_sqlany_connection *sqlany_conn, const char *sql); + typedef a_sqlany_stmt *(*sqlany_prepare_func)(a_sqlany_connection *sqlany_conn, const char *sql_str); + typedef void (*sqlany_free_stmt_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_i32 (*sqlany_num_params_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_bool (*sqlany_describe_bind_param_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param *params); + typedef sacapi_bool (*sqlany_bind_param_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param *params); + typedef sacapi_bool (*sqlany_send_param_data_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, char *buffer, size_t size); + typedef sacapi_bool (*sqlany_reset_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_bool (*sqlany_get_bind_param_info_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, a_sqlany_bind_param_info *info); + typedef sacapi_bool (*sqlany_execute_func)(a_sqlany_stmt *sqlany_stmt); + typedef a_sqlany_stmt *(*sqlany_execute_direct_func)(a_sqlany_connection *sqlany_conn, const char *sql_str); + typedef sacapi_bool (*sqlany_fetch_absolute_func)(a_sqlany_stmt *sqlany_result, sacapi_i32 row_num); + typedef sacapi_bool (*sqlany_fetch_next_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_bool (*sqlany_get_next_result_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_i32 (*sqlany_affected_rows_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_i32 (*sqlany_num_cols_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_i32 (*sqlany_num_rows_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_bool (*sqlany_get_column_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_value *buffer); + typedef sacapi_i32 (*sqlany_get_data_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 col_index, size_t offset, void *buffer, size_t size); + typedef sacapi_bool (*sqlany_get_data_info_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 col_index, a_sqlany_data_info *buffer); + typedef sacapi_bool (*sqlany_get_column_info_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 col_index, a_sqlany_column_info *buffer); + typedef sacapi_bool (*sqlany_commit_func)(a_sqlany_connection *sqlany_conn); + typedef sacapi_bool (*sqlany_rollback_func)(a_sqlany_connection *sqlany_conn); + typedef sacapi_bool (*sqlany_client_version_func)(char *buffer, size_t len); + typedef sacapi_i32 (*sqlany_error_func)(a_sqlany_connection *sqlany_conn, char *buffer, size_t size); + typedef size_t (*sqlany_sqlstate_func)(a_sqlany_connection *sqlany_conn, char *buffer, size_t size); + typedef void (*sqlany_clear_error_func)(a_sqlany_connection *sqlany_conn); +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_2 + typedef a_sqlany_interface_context *(*sqlany_init_ex_func)(const char *app_name, sacapi_u32 api_version, sacapi_u32 *max_version); + typedef void (*sqlany_fini_ex_func)(a_sqlany_interface_context *context); + typedef a_sqlany_connection *(*sqlany_new_connection_ex_func)(a_sqlany_interface_context *context); + typedef a_sqlany_connection *(*sqlany_make_connection_ex_func)(a_sqlany_interface_context *context, void *arg); + typedef sacapi_bool (*sqlany_client_version_ex_func)(a_sqlany_interface_context *context, char *buffer, size_t len); + typedef void (*sqlany_cancel_func)(a_sqlany_connection *sqlany_conn); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_3 - typedef sacapi_bool (*sqlany_register_callback_func)( a_sqlany_connection * sqlany_conn, a_sqlany_callback_type index, SQLANY_CALLBACK_PARM callback ); +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_3 + typedef sacapi_bool (*sqlany_register_callback_func)(a_sqlany_connection *sqlany_conn, a_sqlany_callback_type index, SQLANY_CALLBACK_PARM callback); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_4 - typedef sacapi_bool (*sqlany_set_batch_size_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 num_rows ); - typedef sacapi_bool (*sqlany_set_param_bind_type_func)( a_sqlany_stmt * sqlany_stmt, size_t row_size ); - typedef sacapi_u32 (*sqlany_get_batch_size_func)( a_sqlany_stmt * sqlany_stmt ); - typedef sacapi_bool (*sqlany_set_rowset_size_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 num_rows ); - typedef sacapi_u32 (*sqlany_get_rowset_size_func)( a_sqlany_stmt * sqlany_stmt ); - typedef sacapi_bool (*sqlany_set_column_bind_type_func)( a_sqlany_stmt * sqlany_stmt, size_t row_size ); - typedef sacapi_bool (*sqlany_bind_column_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index, a_sqlany_data_value * value ); - typedef sacapi_bool (*sqlany_clear_column_bindings_func)( a_sqlany_stmt * sqlany_stmt ); - typedef sacapi_i32 (*sqlany_fetched_rows_func)( a_sqlany_stmt * sqlany_stmt ); - typedef sacapi_bool (*sqlany_set_rowset_pos_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 row_num ); +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_4 + typedef sacapi_bool (*sqlany_set_batch_size_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 num_rows); + typedef sacapi_bool (*sqlany_set_param_bind_type_func)(a_sqlany_stmt *sqlany_stmt, size_t row_size); + typedef sacapi_u32 (*sqlany_get_batch_size_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_bool (*sqlany_set_rowset_size_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 num_rows); + typedef sacapi_u32 (*sqlany_get_rowset_size_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_bool (*sqlany_set_column_bind_type_func)(a_sqlany_stmt *sqlany_stmt, size_t row_size); + typedef sacapi_bool (*sqlany_bind_column_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index, a_sqlany_data_value *value); + typedef sacapi_bool (*sqlany_clear_column_bindings_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_i32 (*sqlany_fetched_rows_func)(a_sqlany_stmt *sqlany_stmt); + typedef sacapi_bool (*sqlany_set_rowset_pos_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 row_num); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_5 - typedef sacapi_bool (*sqlany_reset_param_data_func)( a_sqlany_stmt * sqlany_stmt, sacapi_u32 index ); - typedef size_t (*sqlany_error_length_func)( a_sqlany_connection * conn ); +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_5 + typedef sacapi_bool (*sqlany_reset_param_data_func)(a_sqlany_stmt *sqlany_stmt, sacapi_u32 index); + typedef size_t (*sqlany_error_length_func)(a_sqlany_connection *conn); #endif -#if defined( __cplusplus ) +#if defined(__cplusplus) } #endif /// @internal -#define function( x ) x ## _func x +#define function(x) x##_func x /** The SQL Anywhere C API interface structure. * @@ -112,221 +112,222 @@ typedef void (*sqlany_clear_error_func)( a_sqlany_connection * sqlany_conn ); * the SQLAnywhereInterface structure is populated to point to the corresponding functions in the DLL. * \sa sqlany_initialize_interface() */ -typedef struct SQLAnywhereInterface { +typedef struct SQLAnywhereInterface +{ /** DLL handle. */ - void * dll_handle; + void *dll_handle; /** Flag to know if initialized or not. */ - int initialized; + int initialized; /** Pointer to ::sqlany_init() function. */ - function( sqlany_init ); + function(sqlany_init); /** Pointer to ::sqlany_fini() function. */ - function( sqlany_fini ); + function(sqlany_fini); /** Pointer to ::sqlany_new_connection() function. */ - function( sqlany_new_connection ); + function(sqlany_new_connection); /** Pointer to ::sqlany_free_connection() function. */ - function( sqlany_free_connection ); + function(sqlany_free_connection); /** Pointer to ::sqlany_make_connection() function. */ - function( sqlany_make_connection ); + function(sqlany_make_connection); /** Pointer to ::sqlany_connect() function. */ - function( sqlany_connect ); + function(sqlany_connect); /** Pointer to ::sqlany_disconnect() function. */ - function( sqlany_disconnect ); + function(sqlany_disconnect); /** Pointer to ::sqlany_execute_immediate() function. */ - function( sqlany_execute_immediate ); + function(sqlany_execute_immediate); /** Pointer to ::sqlany_prepare() function. */ - function( sqlany_prepare ); + function(sqlany_prepare); /** Pointer to ::sqlany_free_stmt() function. */ - function( sqlany_free_stmt ); + function(sqlany_free_stmt); /** Pointer to ::sqlany_num_params() function. */ - function( sqlany_num_params ); + function(sqlany_num_params); /** Pointer to ::sqlany_describe_bind_param() function. */ - function( sqlany_describe_bind_param ); + function(sqlany_describe_bind_param); /** Pointer to ::sqlany_bind_param() function. */ - function( sqlany_bind_param ); + function(sqlany_bind_param); /** Pointer to ::sqlany_send_param_data() function. */ - function( sqlany_send_param_data ); + function(sqlany_send_param_data); /** Pointer to ::sqlany_reset() function. */ - function( sqlany_reset ); + function(sqlany_reset); /** Pointer to ::sqlany_get_bind_param_info() function. */ - function( sqlany_get_bind_param_info ); + function(sqlany_get_bind_param_info); /** Pointer to ::sqlany_execute() function. */ - function( sqlany_execute ); + function(sqlany_execute); /** Pointer to ::sqlany_execute_direct() function. */ - function( sqlany_execute_direct ); + function(sqlany_execute_direct); /** Pointer to ::sqlany_fetch_absolute() function. */ - function( sqlany_fetch_absolute ); + function(sqlany_fetch_absolute); /** Pointer to ::sqlany_fetch_next() function. */ - function( sqlany_fetch_next ); + function(sqlany_fetch_next); /** Pointer to ::sqlany_get_next_result() function. */ - function( sqlany_get_next_result ); + function(sqlany_get_next_result); /** Pointer to ::sqlany_affected_rows() function. */ - function( sqlany_affected_rows ); + function(sqlany_affected_rows); /** Pointer to ::sqlany_num_cols() function. */ - function( sqlany_num_cols ); + function(sqlany_num_cols); /** Pointer to ::sqlany_num_rows() function. */ - function( sqlany_num_rows ); + function(sqlany_num_rows); /** Pointer to ::sqlany_get_column() function. */ - function( sqlany_get_column ); + function(sqlany_get_column); /** Pointer to ::sqlany_get_data() function. */ - function( sqlany_get_data ); + function(sqlany_get_data); /** Pointer to ::sqlany_get_data_info() function. */ - function( sqlany_get_data_info ); + function(sqlany_get_data_info); /** Pointer to ::sqlany_get_column_info() function. */ - function( sqlany_get_column_info ); + function(sqlany_get_column_info); /** Pointer to ::sqlany_commit() function. */ - function( sqlany_commit ); + function(sqlany_commit); /** Pointer to ::sqlany_rollback() function. */ - function( sqlany_rollback ); + function(sqlany_rollback); /** Pointer to ::sqlany_client_version() function. */ - function( sqlany_client_version ); + function(sqlany_client_version); /** Pointer to ::sqlany_error() function. */ - function( sqlany_error ); + function(sqlany_error); /** Pointer to ::sqlany_sqlstate() function. */ - function( sqlany_sqlstate ); + function(sqlany_sqlstate); /** Pointer to ::sqlany_clear_error() function. */ - function( sqlany_clear_error ); + function(sqlany_clear_error); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_2 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_2 /** Pointer to ::sqlany_init_ex() function. */ - function( sqlany_init_ex ); + function(sqlany_init_ex); /** Pointer to ::sqlany_fini_ex() function. */ - function( sqlany_fini_ex ); + function(sqlany_fini_ex); /** Pointer to ::sqlany_new_connection_ex() function. */ - function( sqlany_new_connection_ex ); + function(sqlany_new_connection_ex); /** Pointer to ::sqlany_make_connection_ex() function. */ - function( sqlany_make_connection_ex ); + function(sqlany_make_connection_ex); /** Pointer to ::sqlany_client_version_ex() function. */ - function( sqlany_client_version_ex ); + function(sqlany_client_version_ex); /** Pointer to ::sqlany_cancel() function. */ - function( sqlany_cancel ); + function(sqlany_cancel); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_3 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_3 /** Pointer to ::sqlany_register_callback() function. */ - function( sqlany_register_callback ); + function(sqlany_register_callback); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_4 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_4 /** Pointer to ::sqlany_set_batch_size() function. */ - function( sqlany_set_batch_size ); + function(sqlany_set_batch_size); /** Pointer to ::sqlany_set_param_bind_type() function. */ - function( sqlany_set_param_bind_type ); + function(sqlany_set_param_bind_type); /** Pointer to ::sqlany_get_batch_size() function. */ - function( sqlany_get_batch_size ); + function(sqlany_get_batch_size); /** Pointer to ::sqlany_set_rowset_size() function. */ - function( sqlany_set_rowset_size ); + function(sqlany_set_rowset_size); /** Pointer to ::sqlany_get_rowset_size() function. */ - function( sqlany_get_rowset_size ); + function(sqlany_get_rowset_size); /** Pointer to ::sqlany_set_column_bind_type() function. */ - function( sqlany_set_column_bind_type ); + function(sqlany_set_column_bind_type); /** Pointer to ::sqlany_bind_column() function. */ - function( sqlany_bind_column ); + function(sqlany_bind_column); /** Pointer to ::sqlany_clear_column_bindings() function. */ - function( sqlany_clear_column_bindings ); + function(sqlany_clear_column_bindings); /** Pointer to ::sqlany_fetched_rows() function. */ - function( sqlany_fetched_rows ); + function(sqlany_fetched_rows); /** Pointer to ::sqlany_set_rowset_pos() function. */ - function( sqlany_set_rowset_pos ); + function(sqlany_set_rowset_pos); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_5 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_5 /** Pointer to ::sqlany_reset_param_data() function. */ - function( sqlany_reset_param_data ); + function(sqlany_reset_param_data); /** Pointer to ::sqlany_error_length() function. */ - function( sqlany_error_length ); + function(sqlany_error_length); #endif } SQLAnywhereInterface; @@ -356,7 +357,7 @@ typedef struct SQLAnywhereInterface { * \param optional_path_to_dll An optional argument that specifies a path to the SQL Anywhere C API DLL. * \return 1 on successful initialization, and 0 on failure. */ -int sqlany_initialize_interface( SQLAnywhereInterface * api, const char * optional_path_to_dll ); +int sqlany_initialize_interface(SQLAnywhereInterface *api, const char *optional_path_to_dll); /** Unloads the C API DLL library and resets the SQLAnywhereInterface structure. * @@ -375,6 +376,6 @@ int sqlany_initialize_interface( SQLAnywhereInterface * api, const char * option * \param api An initialized structure to finalize. */ -void sqlany_finalize_interface( SQLAnywhereInterface * api ); +void sqlany_finalize_interface(SQLAnywhereInterface *api); -#endif +#endif diff --git a/src/h/sqlany_utils.h b/src/h/sqlany_utils.h index 4966724..5f73b5a 100644 --- a/src/h/sqlany_utils.h +++ b/src/h/sqlany_utils.h @@ -4,22 +4,22 @@ #include #include #include -#include +#include #include #include "sacapidll.h" #include "sacapi.h" -#pragma warning (disable : 4100) -#pragma warning (disable : 4506) -#pragma warning (disable : 4068) -#pragma warning (disable : 4800) +#pragma warning(disable : 4100) +#pragma warning(disable : 4506) +#pragma warning(disable : 4068) +#pragma warning(disable : 4800) #pragma GCC diagnostic ignored "-Wunused-parameter" -#if defined( _MSC_VER ) +#if defined(_MSC_VER) // According to the github page for node.js, some warnings generated by // Visual Studio are "overzealous". They should be fixed in VS 2017 15.6. // https://github.com/nodejs/node/issues/17114 -#pragma warning( disable : 4251 ) +#pragma warning(disable : 4251) #endif #include "node.h" #include "v8.h" @@ -28,10 +28,10 @@ #include "uv.h" #pragma GCC diagnostic pop -#pragma warning (default : 4100) -#pragma warning (default : 4506) -#pragma warning (default : 4068) -#pragma warning (default : 4800) +#pragma warning(default : 4100) +#pragma warning(default : 4506) +#pragma warning(default : 4068) +#pragma warning(default : 4800) #include "nodever_cover.h" #include "errors.h" @@ -44,175 +44,147 @@ extern SQLAnywhereInterface api; extern unsigned openConnections; extern uv_mutex_t api_mutex; -#define CLEAN_STRINGS( vector ) \ -{ \ - for( size_t i = 0; i < vector.size(); i++ ) { \ - delete[] vector[i]; \ - } \ - vector.clear(); \ -} - -#define CLEAN_PTRS( vector ) \ -{ \ - for( size_t i = 0; i < vector.size(); i++ ) { \ - delete vector[i]; \ - } \ - vector.clear(); \ -} +#define CLEAN_STRINGS(vector) \ + { \ + for (size_t i = 0; i < vector.size(); i++) \ + { \ + delete[] vector[i]; \ + } \ + vector.clear(); \ + } + +#define CLEAN_PTRS(vector) \ + { \ + for (size_t i = 0; i < vector.size(); i++) \ + { \ + delete vector[i]; \ + } \ + vector.clear(); \ + } class scoped_lock { - public: - scoped_lock( uv_mutex_t &mtx ) : _mtx( mtx ) - { - uv_mutex_lock( &_mtx ); - } - ~scoped_lock() - { - - uv_mutex_unlock( &_mtx ); - } - - private: - uv_mutex_t &_mtx; +public: + scoped_lock(uv_mutex_t &mtx) : _mtx(mtx) + { + uv_mutex_lock(&_mtx); + } + ~scoped_lock() + { + uv_mutex_unlock(&_mtx); + } + +private: + uv_mutex_t &_mtx; }; -class ExecuteData { - public: - ~ExecuteData() { - clear(); +class ExecuteData +{ +public: + ~ExecuteData() + { + clear(); } - void clear( void ) { - CLEAN_STRINGS( string_vals ); - CLEAN_STRINGS( string_arr_vals ); - CLEAN_PTRS( int_vals ); - CLEAN_PTRS( num_vals ); - CLEAN_PTRS( len_vals ); - CLEAN_PTRS( null_vals ); + void clear(void) + { + CLEAN_STRINGS(string_vals); + CLEAN_STRINGS(string_arr_vals); + CLEAN_PTRS(int_vals); + CLEAN_PTRS(num_vals); + CLEAN_PTRS(len_vals); + CLEAN_PTRS(null_vals); } - void addString( char *str, size_t *len ) { - string_vals.push_back( str ); - len_vals.push_back( len ); + void addString(char *str, size_t *len) + { + string_vals.push_back(str); + len_vals.push_back(len); } - void addStrings( char **str, size_t *len ) { - string_arr_vals.push_back( str ); - len_vals.push_back( len ); + void addStrings(char **str, size_t *len) + { + string_arr_vals.push_back(str); + len_vals.push_back(len); } - void addInt( int *val ) { int_vals.push_back( val ); } - void addNum( double *val ) { num_vals.push_back( val ); } - void addNull( sacapi_bool *val ) { null_vals.push_back( val ); } - - char * getString( size_t ind ) { return string_vals[ind]; } - char ** getStrings( size_t ind ) { return string_arr_vals[ind]; } - int getInt( size_t ind ) { return *(int_vals[ind]); } - double getNum( size_t ind ) { return *(num_vals[ind]); } - size_t getLen( size_t ind ) { return *(len_vals[ind]); } - sacapi_bool getNull( size_t ind ) { return *(null_vals[ind]); } - - size_t stringSize( void ) const { return string_vals.size(); } - size_t intSize( void ) const { return int_vals.size(); } - size_t numSize( void ) const { return num_vals.size(); } - size_t lenSize( void ) const { return len_vals.size(); } - size_t nullSize( void ) const { return null_vals.size(); } - - bool stringIsNull( size_t ind ) const { return string_vals[ind] == NULL; } - bool intIsNull( size_t ind ) const { return int_vals[ind] == NULL; } - bool numIsNull( size_t ind ) const { return num_vals[ind] == NULL; } - bool lenIsNull( size_t ind ) const { return string_vals[ind] == NULL; } - bool nullIsNull( size_t ind ) const { return string_vals[ind] == NULL; } - - private: - std::vector string_vals; - std::vector string_arr_vals; - std::vector int_vals; - std::vector num_vals; - std::vector len_vals; - std::vector null_vals; + void addInt(int *val) { int_vals.push_back(val); } + void addNum(double *val) { num_vals.push_back(val); } + void addNull(sacapi_bool *val) { null_vals.push_back(val); } + + char *getString(size_t ind) { return string_vals[ind]; } + char **getStrings(size_t ind) { return string_arr_vals[ind]; } + int getInt(size_t ind) { return *(int_vals[ind]); } + double getNum(size_t ind) { return *(num_vals[ind]); } + size_t getLen(size_t ind) { return *(len_vals[ind]); } + sacapi_bool getNull(size_t ind) { return *(null_vals[ind]); } + + size_t stringSize(void) const { return string_vals.size(); } + size_t intSize(void) const { return int_vals.size(); } + size_t numSize(void) const { return num_vals.size(); } + size_t lenSize(void) const { return len_vals.size(); } + size_t nullSize(void) const { return null_vals.size(); } + + bool stringIsNull(size_t ind) const { return string_vals[ind] == NULL; } + bool intIsNull(size_t ind) const { return int_vals[ind] == NULL; } + bool numIsNull(size_t ind) const { return num_vals[ind] == NULL; } + bool lenIsNull(size_t ind) const { return string_vals[ind] == NULL; } + bool nullIsNull(size_t ind) const { return string_vals[ind] == NULL; } + +private: + std::vector string_vals; + std::vector string_arr_vals; + std::vector int_vals; + std::vector num_vals; + std::vector len_vals; + std::vector null_vals; }; -bool cleanAPI (); // Finalizes the API and frees up resources -void getErrorMsg( a_sqlany_connection *conn, std::string &str ); -void getErrorMsg( int code, std::string &str ); -void throwError( a_sqlany_connection *conn ); -void throwError( int code ); - -#if v010 -void callBack( std::string * str, - Persistent callback, - Local Result, - bool callback_required = true ); -void callBack( std::string * str, - Local callback, - Local Result, - bool callback_required = true ); -#else -void callBack( std::string * str, - Persistent & callback, - Local & Result, - bool callback_required = true ); -void callBack( std::string * str, - const Local & callback, - Local & Result, - bool callback_required = true ); -void callBack( std::string * str, - Persistent & callback, - Persistent & Result, - bool callback_required = true ); -#endif +bool cleanAPI(); // Finalizes the API and frees up resources +void getErrorMsg(a_sqlany_connection *conn, std::string &str); +void getErrorMsg(int code, std::string &str); +void throwError(a_sqlany_connection *conn); +void throwError(int code); -bool getBindParameters( std::vector &execData - , Isolate * isolate - , Local arg - , std::vector ¶ms - , unsigned &num_rows - ); - -#if v010 -bool getResultSet( Local &Result - , int &rows_affected - , std::vector &colNames - , ExecuteData *execData - , std::vector &col_types ); -#else -bool getResultSet( Persistent &Result - , int &rows_affected - , std::vector &colNames - , ExecuteData *execData - , std::vector &col_types ); -#endif +void callBack(std::string *str, + Persistent &callback, + Local &Result, + bool callback_required = true); +void callBack(std::string *str, + const Local &callback, + Local &Result, + bool callback_required = true); +void callBack(std::string *str, + Persistent &callback, + Persistent &Result, + bool callback_required = true); + +bool getBindParameters(std::vector &execData, Isolate *isolate, Local arg, std::vector ¶ms, unsigned &num_rows); + +bool getResultSet(Persistent &Result, int &rows_affected, std::vector &colNames, ExecuteData *execData, std::vector &col_types); + +bool fetchResultSet(a_sqlany_stmt *sqlany_stmt, int &rows_affected, std::vector &colNames, ExecuteData *execData, std::vector &col_types); + +struct noParamBaton +{ + Persistent callback; + bool err; + std::string error_msg; + bool callback_required; -bool fetchResultSet( a_sqlany_stmt *sqlany_stmt - , int &rows_affected - , std::vector &colNames - , ExecuteData *execData - , std::vector &col_types ); - -struct noParamBaton { - Persistent callback; - bool err; - std::string error_msg; - bool callback_required; - Connection *obj; - - noParamBaton() { - obj = NULL; - err = false; + + noParamBaton() + { + obj = NULL; + err = false; } - - ~noParamBaton() { - obj = NULL; + + ~noParamBaton() + { + obj = NULL; } }; -void executeAfter( uv_work_t *req ); -void executeWork( uv_work_t *req ); +void executeAfter(uv_work_t *req); +void executeWork(uv_work_t *req); -#if NODE_MAJOR_VERSION > 0 || NODE_MINOR_VERSION > 10 -void HashToString( Isolate *isolate, Local obj, Persistent &ret ); -#else -Persistent HashToString( Local obj ); -Handle CreateConnection( const Arguments &args ); -#endif +void HashToString(Isolate *isolate, Local obj, Persistent &ret); diff --git a/src/h/stmt.h b/src/h/stmt.h index 56c70df..8b7576a 100644 --- a/src/h/stmt.h +++ b/src/h/stmt.h @@ -14,38 +14,32 @@ using namespace v8; */ class StmtObject : public node::ObjectWrap { - public: - /// @internal -#if v010 - static void Init(); -#else - static void Init( Isolate * ); -#endif - - /// @internal - static NODE_API_FUNC( NewInstance ); +public: + /// @internal + static void Init(Isolate *); - /// @internal -#if !v010 - static void CreateNewInstance( const FunctionCallbackInfo &args, - Persistent &obj ); -#endif + /// @internal + static NODE_API_FUNC(NewInstance); - /// @internal - StmtObject(); - /// @internal - ~StmtObject(); - /// @internal - void cleanup( void ); - void removeConnection( void ); + /// @internal + static void CreateNewInstance(const FunctionCallbackInfo &args, + Persistent &obj); - private: - /// @internal - static Persistent constructor; - /// @internal - static NODE_API_FUNC( New ); - - /** Executes the prepared SQL statement. + /// @internal + StmtObject(); + /// @internal + ~StmtObject(); + /// @internal + void cleanup(void); + void removeConnection(void); + +private: + /// @internal + static Persistent constructor; + /// @internal + static NODE_API_FUNC(New); + + /** Executes the prepared SQL statement. * * This method optionally takes in an array of bind * parameters to execute. @@ -89,9 +83,9 @@ class StmtObject : public node::ObjectWrap * @return If no callback is specified, the result is returned. * */ - static NODE_API_FUNC( exec ); - - /** Drops the statement. + static NODE_API_FUNC(exec); + + /** Drops the statement. * * This method drops the prepared statement and frees up resources. * @@ -125,14 +119,14 @@ class StmtObject : public node::ObjectWrap * @param callback The optional callback function. * */ - static NODE_API_FUNC( drop ); + static NODE_API_FUNC(drop); - /// @internal - static void dropAfter( uv_work_t *req ); - /// @internal - static void dropWork( uv_work_t *req ); + /// @internal + static void dropAfter(uv_work_t *req); + /// @internal + static void dropWork(uv_work_t *req); - /** Gets the next result set of a multi-result-set query. + /** Gets the next result set of a multi-result-set query. * * This method can be either synchronous or asynchronous depending on * whether or not a callback function is specified. @@ -166,11 +160,11 @@ class StmtObject : public node::ObjectWrap * @param callback The optional callback function. * */ - static NODE_API_FUNC( getMoreResults ); + static NODE_API_FUNC(getMoreResults); - public: - /// @internal - Connection *connection; - /// @internal - a_sqlany_stmt *sqlany_stmt; +public: + /// @internal + Connection *connection; + /// @internal + a_sqlany_stmt *sqlany_stmt; }; diff --git a/src/sacapidll.cpp b/src/sacapidll.cpp index a32aae6..9b63697 100644 --- a/src/sacapidll.cpp +++ b/src/sacapidll.cpp @@ -25,181 +25,182 @@ #include #include -#if defined( _WIN32 ) - #include - #define DEFAULT_LIBRARY_NAME "dbcapi.dll" +#if defined(_WIN32) +#include +#define DEFAULT_LIBRARY_NAME "dbcapi.dll" #else - #include - /* assume we are running on a UNIX platform */ - #if defined( __APPLE__ ) - #define LIB_EXT "dylib" - #else - #define LIB_EXT "so" - #endif - #if defined( _REENTRANT ) || defined( _THREAD_SAFE ) \ - || defined( __USE_REENTRANT ) - /* if building a thread-safe library, we need to load +#include +/* assume we are running on a UNIX platform */ +#if defined(__APPLE__) +#define LIB_EXT "dylib" +#else +#define LIB_EXT "so" +#endif +#if defined(_REENTRANT) || defined(_THREAD_SAFE) || defined(__USE_REENTRANT) +/* if building a thread-safe library, we need to load the thread-safe dbcapi library */ - #define DEFAULT_LIBRARY_NAME "libdbcapi_r." LIB_EXT - #else - #define DEFAULT_LIBRARY_NAME "libdbcapi." LIB_EXT - #endif +#define DEFAULT_LIBRARY_NAME "libdbcapi_r." LIB_EXT +#else +#define DEFAULT_LIBRARY_NAME "libdbcapi." LIB_EXT +#endif #endif #include "sacapidll.h" -static -void * loadLibrary( const char * name ) +static void *loadLibrary(const char *name) /*************************************/ { - void * handle; -#if defined( _WIN32 ) - handle = LoadLibrary( name ); + void *handle; +#if defined(_WIN32) + handle = LoadLibrary(name); #else - handle = dlopen( name, RTLD_LAZY ); + handle = dlopen(name, RTLD_LAZY); #endif return handle; } -static -void unloadLibrary( void * handle ) +static void unloadLibrary(void *handle) /**********************************/ { -#if defined( _WIN32 ) - FreeLibrary( (HMODULE)handle ); +#if defined(_WIN32) + FreeLibrary((HMODULE)handle); #else - dlclose( handle ); + dlclose(handle); #endif } -static -void * findSymbol( void * dll_handle, const char * name ) +static void *findSymbol(void *dll_handle, const char *name) /*******************************************************/ { -#if defined( _WIN32 ) - return GetProcAddress( (HMODULE)dll_handle, name ); +#if defined(_WIN32) + return GetProcAddress((HMODULE)dll_handle, name); #else - return dlsym( dll_handle, name ); + return dlsym(dll_handle, name); #endif } -#define LookupSymbol( api, sym ) \ - api->sym = (sym ## _func)findSymbol( api->dll_handle, #sym ); +#define LookupSymbol(api, sym) \ + api->sym = (sym##_func)findSymbol(api->dll_handle, #sym); -#define LookupSymbolAndCheck( api, sym ) \ - api->sym = (sym ## _func)findSymbol( api->dll_handle, #sym ); \ - if( api->sym == NULL ) { \ - unloadLibrary( api->dll_handle ); \ - return 0; \ - } - -int sqlany_initialize_interface( SQLAnywhereInterface * api, const char * path ) +#define LookupSymbolAndCheck(api, sym) \ + api->sym = (sym##_func)findSymbol(api->dll_handle, #sym); \ + if (api->sym == NULL) \ + { \ + unloadLibrary(api->dll_handle); \ + return 0; \ + } + +int sqlany_initialize_interface(SQLAnywhereInterface *api, const char *path) /*******************************************************************************/ { - char * env; - memset( api, 0, sizeof(*api)); + char *env; + memset(api, 0, sizeof(*api)); - if( path != NULL ) { - api->dll_handle = loadLibrary( path ); - if( api->dll_handle != NULL ) { - goto loaded; - } + if (path != NULL) + { + api->dll_handle = loadLibrary(path); + if (api->dll_handle != NULL) + { + goto loaded; + } } - env = getenv( "SQLANY_API_DLL" ); - if( env != NULL ) { - api->dll_handle = loadLibrary( env ); - if( api->dll_handle != NULL ) { - goto loaded; - } + env = getenv("SQLANY_API_DLL"); + if (env != NULL) + { + api->dll_handle = loadLibrary(env); + if (api->dll_handle != NULL) + { + goto loaded; + } } - api->dll_handle = loadLibrary( DEFAULT_LIBRARY_NAME ); - if( api->dll_handle != NULL ) { - goto loaded; + api->dll_handle = loadLibrary(DEFAULT_LIBRARY_NAME); + if (api->dll_handle != NULL) + { + goto loaded; } return 0; loaded: - LookupSymbolAndCheck( api, sqlany_init ); - LookupSymbolAndCheck( api, sqlany_fini ); - LookupSymbolAndCheck( api, sqlany_new_connection ); - LookupSymbolAndCheck( api, sqlany_free_connection ); - LookupSymbolAndCheck( api, sqlany_make_connection ); - LookupSymbolAndCheck( api, sqlany_connect ); - LookupSymbolAndCheck( api, sqlany_disconnect ); - LookupSymbolAndCheck( api, sqlany_execute_immediate ); - LookupSymbolAndCheck( api, sqlany_prepare ); - LookupSymbolAndCheck( api, sqlany_free_stmt ); - LookupSymbolAndCheck( api, sqlany_num_params ); - LookupSymbolAndCheck( api, sqlany_describe_bind_param ); - LookupSymbolAndCheck( api, sqlany_bind_param ); - LookupSymbolAndCheck( api, sqlany_send_param_data ); - LookupSymbolAndCheck( api, sqlany_reset ); - LookupSymbolAndCheck( api, sqlany_get_bind_param_info ); - LookupSymbolAndCheck( api, sqlany_execute ); - LookupSymbolAndCheck( api, sqlany_execute_direct ); - LookupSymbolAndCheck( api, sqlany_fetch_absolute ); - LookupSymbolAndCheck( api, sqlany_fetch_next ); - LookupSymbolAndCheck( api, sqlany_get_next_result ); - LookupSymbolAndCheck( api, sqlany_affected_rows ); - LookupSymbolAndCheck( api, sqlany_num_cols ); - LookupSymbolAndCheck( api, sqlany_num_rows ); - LookupSymbolAndCheck( api, sqlany_get_column ); - LookupSymbolAndCheck( api, sqlany_get_data ); - LookupSymbolAndCheck( api, sqlany_get_data_info ); - LookupSymbolAndCheck( api, sqlany_get_column_info ); - LookupSymbolAndCheck( api, sqlany_commit ); - LookupSymbolAndCheck( api, sqlany_rollback ); - LookupSymbolAndCheck( api, sqlany_client_version ); - LookupSymbolAndCheck( api, sqlany_error ); - LookupSymbolAndCheck( api, sqlany_sqlstate ); - LookupSymbolAndCheck( api, sqlany_clear_error ); + LookupSymbolAndCheck(api, sqlany_init); + LookupSymbolAndCheck(api, sqlany_fini); + LookupSymbolAndCheck(api, sqlany_new_connection); + LookupSymbolAndCheck(api, sqlany_free_connection); + LookupSymbolAndCheck(api, sqlany_make_connection); + LookupSymbolAndCheck(api, sqlany_connect); + LookupSymbolAndCheck(api, sqlany_disconnect); + LookupSymbolAndCheck(api, sqlany_execute_immediate); + LookupSymbolAndCheck(api, sqlany_prepare); + LookupSymbolAndCheck(api, sqlany_free_stmt); + LookupSymbolAndCheck(api, sqlany_num_params); + LookupSymbolAndCheck(api, sqlany_describe_bind_param); + LookupSymbolAndCheck(api, sqlany_bind_param); + LookupSymbolAndCheck(api, sqlany_send_param_data); + LookupSymbolAndCheck(api, sqlany_reset); + LookupSymbolAndCheck(api, sqlany_get_bind_param_info); + LookupSymbolAndCheck(api, sqlany_execute); + LookupSymbolAndCheck(api, sqlany_execute_direct); + LookupSymbolAndCheck(api, sqlany_fetch_absolute); + LookupSymbolAndCheck(api, sqlany_fetch_next); + LookupSymbolAndCheck(api, sqlany_get_next_result); + LookupSymbolAndCheck(api, sqlany_affected_rows); + LookupSymbolAndCheck(api, sqlany_num_cols); + LookupSymbolAndCheck(api, sqlany_num_rows); + LookupSymbolAndCheck(api, sqlany_get_column); + LookupSymbolAndCheck(api, sqlany_get_data); + LookupSymbolAndCheck(api, sqlany_get_data_info); + LookupSymbolAndCheck(api, sqlany_get_column_info); + LookupSymbolAndCheck(api, sqlany_commit); + LookupSymbolAndCheck(api, sqlany_rollback); + LookupSymbolAndCheck(api, sqlany_client_version); + LookupSymbolAndCheck(api, sqlany_error); + LookupSymbolAndCheck(api, sqlany_sqlstate); + LookupSymbolAndCheck(api, sqlany_clear_error); -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_2 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_2 /* We don't report an error if we don't find the v2 entry points. That allows the calling app to revert to v1 */ - LookupSymbol( api, sqlany_init_ex ); - LookupSymbol( api, sqlany_fini_ex ); - LookupSymbol( api, sqlany_new_connection_ex ); - LookupSymbol( api, sqlany_make_connection_ex ); - LookupSymbol( api, sqlany_client_version_ex ); - LookupSymbolAndCheck( api, sqlany_cancel ); + LookupSymbol(api, sqlany_init_ex); + LookupSymbol(api, sqlany_fini_ex); + LookupSymbol(api, sqlany_new_connection_ex); + LookupSymbol(api, sqlany_make_connection_ex); + LookupSymbol(api, sqlany_client_version_ex); + LookupSymbolAndCheck(api, sqlany_cancel); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_3 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_3 /* We don't report an error if we don't find the v3 entry points. That allows the calling app to revert to v1 */ - LookupSymbol( api, sqlany_register_callback ); + LookupSymbol(api, sqlany_register_callback); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_4 +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_4 /* We don't report an error if we don't find the v4 entry points. That allows the calling app to revert to v1 */ - LookupSymbol( api, sqlany_set_batch_size ); - LookupSymbol( api, sqlany_set_param_bind_type ); - LookupSymbol( api, sqlany_get_batch_size ); - LookupSymbol( api, sqlany_set_rowset_size ); - LookupSymbol( api, sqlany_get_rowset_size ); - LookupSymbol( api, sqlany_set_column_bind_type ); - LookupSymbol( api, sqlany_bind_column ); - LookupSymbol( api, sqlany_clear_column_bindings ); - LookupSymbol( api, sqlany_fetched_rows ); - LookupSymbol( api, sqlany_set_rowset_pos ); + LookupSymbol(api, sqlany_set_batch_size); + LookupSymbol(api, sqlany_set_param_bind_type); + LookupSymbol(api, sqlany_get_batch_size); + LookupSymbol(api, sqlany_set_rowset_size); + LookupSymbol(api, sqlany_get_rowset_size); + LookupSymbol(api, sqlany_set_column_bind_type); + LookupSymbol(api, sqlany_bind_column); + LookupSymbol(api, sqlany_clear_column_bindings); + LookupSymbol(api, sqlany_fetched_rows); + LookupSymbol(api, sqlany_set_rowset_pos); #endif -#if _SACAPI_VERSION+0 >= SQLANY_API_VERSION_5 - LookupSymbol( api, sqlany_reset_param_data ); - LookupSymbol( api, sqlany_error_length ); +#if _SACAPI_VERSION + 0 >= SQLANY_API_VERSION_5 + LookupSymbol(api, sqlany_reset_param_data); + LookupSymbol(api, sqlany_error_length); #endif api->initialized = 1; return 1; } #undef LookupSymbolAndCheck -void sqlany_finalize_interface( SQLAnywhereInterface * api ) +void sqlany_finalize_interface(SQLAnywhereInterface *api) /***********************************************************/ { - if( !api->initialized ) { - return; + if (!api->initialized) + { + return; } - unloadLibrary( api->dll_handle ); - memset( api, 0, sizeof(*api)); + unloadLibrary(api->dll_handle); + memset(api, 0, sizeof(*api)); } - - diff --git a/src/sqlanywhere.cpp b/src/sqlanywhere.cpp index ea6f874..46178ca 100644 --- a/src/sqlanywhere.cpp +++ b/src/sqlanywhere.cpp @@ -4,368 +4,409 @@ #include "nodever_cover.h" #include "sqlany_utils.h" -#if !v010 - using namespace v8; SQLAnywhereInterface api; unsigned openConnections = 0; uv_mutex_t api_mutex; -struct executeBaton { - Persistent callback; - bool err; - std::string error_msg; - bool callback_required; - unsigned num_rows; - - Connection *obj; - StmtObject *stmt_obj; - - bool free_stmt; - std::string stmt; - std::vector execData; - std::vector params; - - std::vector colNames; - int rows_affected; - std::vector col_types; - - executeBaton() { - err = false; - callback_required = false; - obj = NULL; - stmt_obj = NULL; - rows_affected = -1; - free_stmt = false; - num_rows = 0; - } - - ~executeBaton() { - obj = NULL; - if( stmt_obj != NULL && free_stmt ) { - delete stmt_obj; - stmt_obj = NULL; - } - col_types.clear(); - callback.Reset(); - params.clear(); - CLEAN_STRINGS( colNames ); - CLEAN_PTRS( execData ); +struct executeBaton +{ + Persistent callback; + bool err; + std::string error_msg; + bool callback_required; + unsigned num_rows; + + Connection *obj; + StmtObject *stmt_obj; + + bool free_stmt; + std::string stmt; + std::vector execData; + std::vector params; + + std::vector colNames; + int rows_affected; + std::vector col_types; + + executeBaton() + { + err = false; + callback_required = false; + obj = NULL; + stmt_obj = NULL; + rows_affected = -1; + free_stmt = false; + num_rows = 0; + } + + ~executeBaton() + { + obj = NULL; + if (stmt_obj != NULL && free_stmt) + { + delete stmt_obj; + stmt_obj = NULL; + } + col_types.clear(); + callback.Reset(); + params.clear(); + CLEAN_STRINGS(colNames); + CLEAN_PTRS(execData); } }; -static bool fillResult( executeBaton *baton, Persistent &ResultSet ) +static bool fillResult(executeBaton *baton, Persistent &ResultSet) /*************************************************************************/ { Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - Local undef = Local::New( isolate, Undefined( isolate ) ); + HandleScope scope(isolate); + Local undef = Local::New(isolate, Undefined(isolate)); - if( baton->err ) { - callBack( &( baton->error_msg ), baton->callback, undef, - baton->callback_required ); - return false; + if (baton->err) + { + callBack(&(baton->error_msg), baton->callback, undef, + baton->callback_required); + return false; } // We don't support wide fetches - if( !getResultSet( ResultSet, baton->rows_affected, baton->colNames, - baton->execData[0], baton->col_types ) ) { - getErrorMsg( JS_ERR_RESULTSET, baton->error_msg ); - callBack( &( baton->error_msg ), baton->callback, undef, - baton->callback_required ); - return false; + if (!getResultSet(ResultSet, baton->rows_affected, baton->colNames, + baton->execData[0], baton->col_types)) + { + getErrorMsg(JS_ERR_RESULTSET, baton->error_msg); + callBack(&(baton->error_msg), baton->callback, undef, + baton->callback_required); + return false; } - if( baton->callback_required ) { - callBack( NULL, baton->callback, ResultSet, baton->callback_required ); + if (baton->callback_required) + { + callBack(NULL, baton->callback, ResultSet, baton->callback_required); } return true; } -void executeWork( uv_work_t *req ) +void executeWork(uv_work_t *req) /********************************/ { - executeBaton *baton = static_cast(req->data); - scoped_lock lock( baton->obj->conn_mutex ); + executeBaton *baton = static_cast(req->data); + scoped_lock lock(baton->obj->conn_mutex); - if( baton->obj->conn == NULL ) { - baton->err = true; - getErrorMsg( JS_ERR_NOT_CONNECTED, baton->error_msg ); - return; + if (baton->obj->conn == NULL) + { + baton->err = true; + getErrorMsg(JS_ERR_NOT_CONNECTED, baton->error_msg); + return; } - + a_sqlany_stmt *sqlany_stmt = NULL; - if( baton->stmt_obj == NULL ) { - baton->stmt_obj = new StmtObject(); - baton->stmt_obj->connection = baton->obj; - baton->obj->statements.push_back( baton->stmt_obj ); - } else { - sqlany_stmt = baton->stmt_obj->sqlany_stmt; - } - - if( sqlany_stmt == NULL && baton->stmt.length() > 0 ) { - sqlany_stmt = api.sqlany_prepare( baton->obj->conn, - baton->stmt.c_str() ); - if( sqlany_stmt == NULL ) { - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - return; - } - baton->stmt_obj->sqlany_stmt = sqlany_stmt; - - } else if( sqlany_stmt == NULL ) { - baton->err = true; - getErrorMsg( JS_ERR_INVALID_OBJECT, baton->error_msg ); - return; - } - - if( !api.sqlany_reset( sqlany_stmt ) ) { - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - return; - } - - for( unsigned int i = 0; i < baton->params.size(); i++ ) { - a_sqlany_bind_param param; - - if( !api.sqlany_describe_bind_param( sqlany_stmt, i, ¶m ) ) { - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - return; - } - - memcpy( ¶m.value, &baton->params[i].value, sizeof( param.value ) ); - - if( !api.sqlany_bind_param( sqlany_stmt, i, ¶m ) ) { - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - return; - } - } - - if( baton->num_rows > 1 ) { - api.sqlany_set_batch_size( sqlany_stmt, baton->num_rows ); - } - - sacapi_bool success_execute = api.sqlany_execute( sqlany_stmt ); + if (baton->stmt_obj == NULL) + { + baton->stmt_obj = new StmtObject(); + baton->stmt_obj->connection = baton->obj; + baton->obj->statements.push_back(baton->stmt_obj); + } + else + { + sqlany_stmt = baton->stmt_obj->sqlany_stmt; + } + + if (sqlany_stmt == NULL && baton->stmt.length() > 0) + { + sqlany_stmt = api.sqlany_prepare(baton->obj->conn, + baton->stmt.c_str()); + if (sqlany_stmt == NULL) + { + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + return; + } + baton->stmt_obj->sqlany_stmt = sqlany_stmt; + } + else if (sqlany_stmt == NULL) + { + baton->err = true; + getErrorMsg(JS_ERR_INVALID_OBJECT, baton->error_msg); + return; + } + + if (!api.sqlany_reset(sqlany_stmt)) + { + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + return; + } + + for (unsigned int i = 0; i < baton->params.size(); i++) + { + a_sqlany_bind_param param; + + if (!api.sqlany_describe_bind_param(sqlany_stmt, i, ¶m)) + { + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + return; + } + + memcpy(¶m.value, &baton->params[i].value, sizeof(param.value)); + + if (!api.sqlany_bind_param(sqlany_stmt, i, ¶m)) + { + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + return; + } + } + + if (baton->num_rows > 1) + { + api.sqlany_set_batch_size(sqlany_stmt, baton->num_rows); + } + + sacapi_bool success_execute = api.sqlany_execute(sqlany_stmt); baton->execData[0]->clear(); - if( !success_execute ) { - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - return; + if (!success_execute) + { + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + return; } - - if( !fetchResultSet( sqlany_stmt, baton->rows_affected, baton->colNames, - baton->execData[0], baton->col_types ) ) { - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - return; + + if (!fetchResultSet(sqlany_stmt, baton->rows_affected, baton->colNames, + baton->execData[0], baton->col_types)) + { + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + return; } } -void executeAfter( uv_work_t *req ) +void executeAfter(uv_work_t *req) /*********************************/ { Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - executeBaton *baton = static_cast( req->data ); + HandleScope scope(isolate); + executeBaton *baton = static_cast(req->data); Persistent ResultSet; - fillResult( baton, ResultSet ); + fillResult(baton, ResultSet); ResultSet.Reset(); delete baton; delete req; } -NODE_API_FUNC( StmtObject::exec ) +NODE_API_FUNC(StmtObject::exec) /*******************************/ { Isolate *isolate = args.GetIsolate(); - HandleScope scope( isolate ); - StmtObject *obj = ObjectWrap::Unwrap( args.This() ); + HandleScope scope(isolate); + StmtObject *obj = ObjectWrap::Unwrap(args.This()); int num_args = args.Length(); bool callback_required = false, bind_required = false; int cbfunc_arg = -1; - Local undef = Local::New( isolate, Undefined( isolate ) ); - - if( num_args == 0 ) { - - } else if( num_args == 1 && args[0]->IsArray() ) { - bind_required = true; - - } else if( num_args == 1 && args[0]->IsFunction() ) { - callback_required = true; - cbfunc_arg = 0; - - } else if( num_args == 2 && args[0]->IsArray() && args[1]->IsFunction() ) { - callback_required = true; - bind_required = true; - cbfunc_arg = 1; - - } else { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - - if( obj == NULL || obj->connection == NULL || obj->connection->conn == NULL || - obj->sqlany_stmt == NULL ) { - std::string error_msg; - getErrorMsg( JS_ERR_INVALID_OBJECT, error_msg ); - callBack( &( error_msg ), args[cbfunc_arg], undef, callback_required ); - args.GetReturnValue().SetUndefined(); - return; - } - + Local undef = Local::New(isolate, Undefined(isolate)); + + if (num_args == 0) + { + } + else if (num_args == 1 && args[0]->IsArray()) + { + bind_required = true; + } + else if (num_args == 1 && args[0]->IsFunction()) + { + callback_required = true; + cbfunc_arg = 0; + } + else if (num_args == 2 && args[0]->IsArray() && args[1]->IsFunction()) + { + callback_required = true; + bind_required = true; + cbfunc_arg = 1; + } + else + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + + if (obj == NULL || obj->connection == NULL || obj->connection->conn == NULL || + obj->sqlany_stmt == NULL) + { + std::string error_msg; + getErrorMsg(JS_ERR_INVALID_OBJECT, error_msg); + callBack(&(error_msg), args[cbfunc_arg], undef, callback_required); + args.GetReturnValue().SetUndefined(); + return; + } + executeBaton *baton = new executeBaton(); baton->obj = obj->connection; baton->stmt_obj = obj; baton->free_stmt = false; baton->callback_required = callback_required; - if( bind_required ) { - if( !getBindParameters( baton->execData, isolate, args[0], baton->params, - baton->num_rows ) ) { - delete baton; - std::string error_msg; - getErrorMsg( JS_ERR_BINDING_PARAMETERS, error_msg ); - callBack( &( error_msg ), args[cbfunc_arg], undef, callback_required ); - args.GetReturnValue().SetUndefined(); - return; - } - if( baton->num_rows > 1 && - baton->obj->max_api_ver < SQLANY_API_VERSION_4 ) { - // can't support wide inserts with older dbcapi - delete baton; - std::string error_msg; - getErrorMsg( JS_ERR_NO_WIDE_STATEMENTS, error_msg ); - callBack( &( error_msg ), args[cbfunc_arg], undef, callback_required ); - args.GetReturnValue().SetUndefined(); - return; - } - } else { - baton->execData.push_back( new ExecuteData ); - baton->num_rows = 1; + if (bind_required) + { + if (!getBindParameters(baton->execData, isolate, args[0], baton->params, + baton->num_rows)) + { + delete baton; + std::string error_msg; + getErrorMsg(JS_ERR_BINDING_PARAMETERS, error_msg); + callBack(&(error_msg), args[cbfunc_arg], undef, callback_required); + args.GetReturnValue().SetUndefined(); + return; + } + if (baton->num_rows > 1 && + baton->obj->max_api_ver < SQLANY_API_VERSION_4) + { + // can't support wide inserts with older dbcapi + delete baton; + std::string error_msg; + getErrorMsg(JS_ERR_NO_WIDE_STATEMENTS, error_msg); + callBack(&(error_msg), args[cbfunc_arg], undef, callback_required); + args.GetReturnValue().SetUndefined(); + return; + } + } + else + { + baton->execData.push_back(new ExecuteData); + baton->num_rows = 1; } uv_work_t *req = new uv_work_t(); req->data = baton; - - if( callback_required ) { - Local callback = Local::Cast(args[cbfunc_arg]); - baton->callback.Reset( isolate, callback ); - - int status; - status = uv_queue_work( uv_default_loop(), req, executeWork, - (uv_after_work_cb)executeAfter ); - assert(status == 0); - - args.GetReturnValue().SetUndefined(); - return; - } - + + if (callback_required) + { + Local callback = Local::Cast(args[cbfunc_arg]); + baton->callback.Reset(isolate, callback); + + int status; + status = uv_queue_work(uv_default_loop(), req, executeWork, + (uv_after_work_cb)executeAfter); + assert(status == 0); + + args.GetReturnValue().SetUndefined(); + return; + } + Persistent ResultSet; - - executeWork( req ); - bool success = fillResult( baton, ResultSet ); + + executeWork(req); + bool success = fillResult(baton, ResultSet); delete baton; delete req; - - if( !success ) { - args.GetReturnValue().SetUndefined(); - return; + + if (!success) + { + args.GetReturnValue().SetUndefined(); + return; } - args.GetReturnValue().Set( ResultSet ); + args.GetReturnValue().Set(ResultSet.Get(isolate)); ResultSet.Reset(); } -void getMoreResultsWork( uv_work_t *req ) +void getMoreResultsWork(uv_work_t *req) /***************************************/ { - executeBaton *baton = static_cast(req->data); - scoped_lock lock( baton->obj->conn_mutex ); + executeBaton *baton = static_cast(req->data); + scoped_lock lock(baton->obj->conn_mutex); - if( baton->obj->conn == NULL ) { - baton->err = true; - getErrorMsg( JS_ERR_NOT_CONNECTED, baton->error_msg ); - return; + if (baton->obj->conn == NULL) + { + baton->err = true; + getErrorMsg(JS_ERR_NOT_CONNECTED, baton->error_msg); + return; } a_sqlany_stmt *stmt = baton->stmt_obj->sqlany_stmt; - if( stmt == NULL ) { - baton->err = true; - getErrorMsg( JS_ERR_INVALID_OBJECT, baton->error_msg ); - return; - } - int retval = ( api.sqlany_get_next_result( stmt ) != 0 ); - if( !retval ) { - char buffer[SACAPI_ERROR_SIZE]; - int rc; - rc = api.sqlany_error( baton->obj->conn, buffer, sizeof(buffer) ); - if( rc != 105 ) { - // rc == 105 means "procedure has completed" - i.e. no more result - // sets. Just return null, not an error - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - } - return; + if (stmt == NULL) + { + baton->err = true; + getErrorMsg(JS_ERR_INVALID_OBJECT, baton->error_msg); + return; + } + int retval = (api.sqlany_get_next_result(stmt) != 0); + if (!retval) + { + char buffer[SACAPI_ERROR_SIZE]; + int rc; + rc = api.sqlany_error(baton->obj->conn, buffer, sizeof(buffer)); + if (rc != 105) + { + // rc == 105 means "procedure has completed" - i.e. no more result + // sets. Just return null, not an error + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + } + return; } baton->execData[0]->clear(); - if( !fetchResultSet( stmt, baton->rows_affected, baton->colNames, - baton->execData[0], baton->col_types ) ) { - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - return; + if (!fetchResultSet(stmt, baton->rows_affected, baton->colNames, + baton->execData[0], baton->col_types)) + { + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + return; } } -void getMoreResultsAfter( uv_work_t *req ) +void getMoreResultsAfter(uv_work_t *req) /****************************************/ { Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - executeBaton *baton = static_cast( req->data ); + HandleScope scope(isolate); + executeBaton *baton = static_cast(req->data); Persistent ResultSet; - fillResult( baton, ResultSet ); + fillResult(baton, ResultSet); ResultSet.Reset(); delete baton; delete req; } -NODE_API_FUNC( StmtObject::getMoreResults ) +NODE_API_FUNC(StmtObject::getMoreResults) /*****************************************/ { Isolate *isolate = args.GetIsolate(); - HandleScope scope( isolate ); - StmtObject *obj = ObjectWrap::Unwrap( args.This() ); + HandleScope scope(isolate); + StmtObject *obj = ObjectWrap::Unwrap(args.This()); int num_args = args.Length(); bool callback_required = false; int cbfunc_arg = -1; - Local undef = Local::New( isolate, Undefined( isolate ) ); - - if( num_args == 0 ) { - - } else if( num_args == 1 && args[0]->IsFunction() ) { - callback_required = true; - cbfunc_arg = 0; - - } else { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - - if( obj == NULL || obj->connection == NULL || obj->connection->conn == NULL || - obj->sqlany_stmt == NULL ) { - std::string error_msg; - getErrorMsg( JS_ERR_INVALID_OBJECT, error_msg ); - callBack( &( error_msg ), args[cbfunc_arg], undef, callback_required ); - args.GetReturnValue().SetUndefined(); - return; + Local undef = Local::New(isolate, Undefined(isolate)); + + if (num_args == 0) + { + } + else if (num_args == 1 && args[0]->IsFunction()) + { + callback_required = true; + cbfunc_arg = 0; + } + else + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + + if (obj == NULL || obj->connection == NULL || obj->connection->conn == NULL || + obj->sqlany_stmt == NULL) + { + std::string error_msg; + getErrorMsg(JS_ERR_INVALID_OBJECT, error_msg); + callBack(&(error_msg), args[cbfunc_arg], undef, callback_required); + args.GetReturnValue().SetUndefined(); + return; } executeBaton *baton = new executeBaton; @@ -374,93 +415,99 @@ NODE_API_FUNC( StmtObject::getMoreResults ) baton->free_stmt = false; baton->callback_required = callback_required; - baton->execData.push_back( new ExecuteData ); + baton->execData.push_back(new ExecuteData); baton->num_rows = 1; uv_work_t *req = new uv_work_t(); req->data = baton; - - if( callback_required ) { - Local callback = Local::Cast(args[cbfunc_arg]); - baton->callback.Reset( isolate, callback ); - - int status; - status = uv_queue_work( uv_default_loop(), req, getMoreResultsWork, - (uv_after_work_cb)getMoreResultsAfter ); - assert(status == 0); - - args.GetReturnValue().SetUndefined(); - return; - } - + + if (callback_required) + { + Local callback = Local::Cast(args[cbfunc_arg]); + baton->callback.Reset(isolate, callback); + + int status; + status = uv_queue_work(uv_default_loop(), req, getMoreResultsWork, + (uv_after_work_cb)getMoreResultsAfter); + assert(status == 0); + + args.GetReturnValue().SetUndefined(); + return; + } + Persistent ResultSet; - - getMoreResultsWork( req ); - bool success = fillResult( baton, ResultSet ); + + getMoreResultsWork(req); + bool success = fillResult(baton, ResultSet); delete baton; delete req; - - if( !success ) { - args.GetReturnValue().SetUndefined(); - return; + + if (!success) + { + args.GetReturnValue().SetUndefined(); + return; } - args.GetReturnValue().Set( ResultSet ); + args.GetReturnValue().Set(ResultSet.Get(isolate)); ResultSet.Reset(); } -NODE_API_FUNC( Connection::exec ) +NODE_API_FUNC(Connection::exec) /*******************************/ { Isolate *isolate = args.GetIsolate(); Local context = isolate->GetCurrentContext(); - HandleScope scope( isolate ); - Local undef = Local::New( isolate, Undefined( isolate ) ); + HandleScope scope(isolate); + Local undef = Local::New(isolate, Undefined(isolate)); int num_args = args.Length(); bool callback_required = false, bind_required = false; int cbfunc_arg = 0; - if( args[0]->IsString() ) { - if( num_args == 1 ) { - - } else if( num_args == 2 && args[1]->IsArray() ) { - bind_required = true; - - } else if( num_args == 2 && args[1]->IsFunction() ) { - callback_required = true; - cbfunc_arg = 1; - - } else if( num_args == 3 && args[1]->IsArray() && args[2]->IsFunction() ) { - callback_required = true; - bind_required = true; - cbfunc_arg = 2; - - } else { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - } else { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - - Connection *obj = ObjectWrap::Unwrap( args.This() ); - - if( obj == NULL || obj->conn == NULL ) { - std::string error_msg; - getErrorMsg( JS_ERR_INVALID_OBJECT, error_msg ); - callBack( &( error_msg ), args[cbfunc_arg], undef, callback_required ); - args.GetReturnValue().SetUndefined(); - return; - } - -#if NODE_MAJOR_VERSION >= 12 - String::Utf8Value param0( isolate, (args[0]->ToString(context)).ToLocalChecked() ); -#else - String::Utf8Value param0( (args[0]->ToString(context)).ToLocalChecked() ); -#endif + if (args[0]->IsString()) + { + if (num_args == 1) + { + } + else if (num_args == 2 && args[1]->IsArray()) + { + bind_required = true; + } + else if (num_args == 2 && args[1]->IsFunction()) + { + callback_required = true; + cbfunc_arg = 1; + } + else if (num_args == 3 && args[1]->IsArray() && args[2]->IsFunction()) + { + callback_required = true; + bind_required = true; + cbfunc_arg = 2; + } + else + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + } + else + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + Connection *obj = ObjectWrap::Unwrap(args.This()); + + if (obj == NULL || obj->conn == NULL) + { + std::string error_msg; + getErrorMsg(JS_ERR_INVALID_OBJECT, error_msg); + callBack(&(error_msg), args[cbfunc_arg], undef, callback_required); + args.GetReturnValue().SetUndefined(); + return; + } + + String::Utf8Value param0(isolate, (args[0]->ToString(context)).ToLocalChecked()); executeBaton *baton = new executeBaton(); baton->obj = obj; baton->callback_required = callback_required; @@ -468,803 +515,863 @@ NODE_API_FUNC( Connection::exec ) baton->stmt_obj = NULL; baton->stmt = std::string(*param0); - if( bind_required ) { - if( !getBindParameters( baton->execData, isolate, args[1], baton->params, - baton->num_rows ) ) { - delete baton; - std::string error_msg; - getErrorMsg( JS_ERR_BINDING_PARAMETERS, error_msg ); - callBack( &( error_msg ), args[cbfunc_arg], undef, callback_required ); - args.GetReturnValue().SetUndefined(); - return; - } - if( baton->num_rows > 1 && - baton->obj->max_api_ver < SQLANY_API_VERSION_4 ) { - // can't support wide inserts with older dbcapi - delete baton; - std::string error_msg; - getErrorMsg( JS_ERR_NO_WIDE_STATEMENTS, error_msg ); - callBack( &( error_msg ), args[cbfunc_arg], undef, callback_required ); - args.GetReturnValue().SetUndefined(); - return; - } - } else { - baton->execData.push_back( new ExecuteData ); - baton->num_rows = 1; - } - + if (bind_required) + { + if (!getBindParameters(baton->execData, isolate, args[1], baton->params, + baton->num_rows)) + { + delete baton; + std::string error_msg; + getErrorMsg(JS_ERR_BINDING_PARAMETERS, error_msg); + callBack(&(error_msg), args[cbfunc_arg], undef, callback_required); + args.GetReturnValue().SetUndefined(); + return; + } + if (baton->num_rows > 1 && + baton->obj->max_api_ver < SQLANY_API_VERSION_4) + { + // can't support wide inserts with older dbcapi + delete baton; + std::string error_msg; + getErrorMsg(JS_ERR_NO_WIDE_STATEMENTS, error_msg); + callBack(&(error_msg), args[cbfunc_arg], undef, callback_required); + args.GetReturnValue().SetUndefined(); + return; + } + } + else + { + baton->execData.push_back(new ExecuteData); + baton->num_rows = 1; + } + uv_work_t *req = new uv_work_t(); req->data = baton; - - if( callback_required ) { - Local callback = Local::Cast(args[cbfunc_arg]); - baton->callback.Reset( isolate, callback ); - int status; - status = uv_queue_work( uv_default_loop(), req, executeWork, - (uv_after_work_cb)executeAfter ); - assert(status == 0); - - args.GetReturnValue().SetUndefined(); - return; - } - + + if (callback_required) + { + Local callback = Local::Cast(args[cbfunc_arg]); + baton->callback.Reset(isolate, callback); + int status; + status = uv_queue_work(uv_default_loop(), req, executeWork, + (uv_after_work_cb)executeAfter); + assert(status == 0); + + args.GetReturnValue().SetUndefined(); + return; + } + Persistent ResultSet; - executeWork( req ); - bool success = fillResult( baton, ResultSet ); + executeWork(req); + bool success = fillResult(baton, ResultSet); delete baton; delete req; - - if( !success ) { - args.GetReturnValue().SetUndefined(); - return; + + if (!success) + { + args.GetReturnValue().SetUndefined(); + return; } - Local local_result = Local::New( isolate, ResultSet ); - args.GetReturnValue().Set( local_result ); + Local local_result = Local::New(isolate, ResultSet); + args.GetReturnValue().Set(local_result); ResultSet.Reset(); } -struct prepareBaton { - Persistent callback; - bool err; - std::string error_msg; - bool callback_required; - - StmtObject *obj; - std::string stmt; - Persistent StmtObj; - - prepareBaton() { - err = false; - callback_required = false; - obj = NULL; - } - - ~prepareBaton() { - obj = NULL; - callback.Reset(); - StmtObj.Reset(); +struct prepareBaton +{ + Persistent callback; + bool err; + std::string error_msg; + bool callback_required; + + StmtObject *obj; + std::string stmt; + Persistent StmtObj; + + prepareBaton() + { + err = false; + callback_required = false; + obj = NULL; + } + + ~prepareBaton() + { + obj = NULL; + callback.Reset(); + StmtObj.Reset(); } }; -void Connection::prepareWork( uv_work_t *req ) +void Connection::prepareWork(uv_work_t *req) /*********************************************/ { - prepareBaton *baton = static_cast(req->data); - if( baton->obj == NULL || baton->obj->connection == NULL || - baton->obj->connection->conn == NULL ) { - baton->err = true; - getErrorMsg( JS_ERR_INVALID_OBJECT, baton->error_msg ); - return; - } - - scoped_lock lock( baton->obj->connection->conn_mutex ); - - baton->obj->sqlany_stmt = api.sqlany_prepare( baton->obj->connection->conn, - baton->stmt.c_str() ); - - if( baton->obj->sqlany_stmt == NULL ) { - baton->err = true; - getErrorMsg( baton->obj->connection->conn, baton->error_msg ); - return; + prepareBaton *baton = static_cast(req->data); + if (baton->obj == NULL || baton->obj->connection == NULL || + baton->obj->connection->conn == NULL) + { + baton->err = true; + getErrorMsg(JS_ERR_INVALID_OBJECT, baton->error_msg); + return; + } + + scoped_lock lock(baton->obj->connection->conn_mutex); + + baton->obj->sqlany_stmt = api.sqlany_prepare(baton->obj->connection->conn, + baton->stmt.c_str()); + + if (baton->obj->sqlany_stmt == NULL) + { + baton->err = true; + getErrorMsg(baton->obj->connection->conn, baton->error_msg); + return; } } -void Connection::prepareAfter( uv_work_t *req ) +void Connection::prepareAfter(uv_work_t *req) /**********************************************/ { Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - prepareBaton *baton = static_cast(req->data); - Local undef = Local::New( isolate, Undefined( isolate ) ); - - if( baton->err ) { - callBack( &( baton->error_msg ), baton->callback, undef, - baton->callback_required ); - delete baton; - delete req; - return; - } - - if( baton->callback_required ) { - Local StmtObj = Local::New( isolate, baton->StmtObj ); - callBack( NULL, baton->callback, StmtObj, baton->callback_required ); - baton->StmtObj.Reset(); - } - + HandleScope scope(isolate); + prepareBaton *baton = static_cast(req->data); + Local undef = Local::New(isolate, Undefined(isolate)); + + if (baton->err) + { + callBack(&(baton->error_msg), baton->callback, undef, + baton->callback_required); + delete baton; + delete req; + return; + } + + if (baton->callback_required) + { + Local StmtObj = Local::New(isolate, baton->StmtObj); + callBack(NULL, baton->callback, StmtObj, baton->callback_required); + baton->StmtObj.Reset(); + } + delete baton; delete req; } -NODE_API_FUNC( Connection::prepare ) +NODE_API_FUNC(Connection::prepare) /**********************************/ { Isolate *isolate = args.GetIsolate(); Local context = isolate->GetCurrentContext(); - HandleScope scope( isolate ); + HandleScope scope(isolate); bool callback_required = false; int cbfunc_arg = -1; - Local undef = Local::New( isolate, Undefined( isolate ) ); - - if( args.Length() == 1 && args[0]->IsString() ) { - // do nothing - } else if( args.Length() == 2 && args[0]->IsString() && args[1]->IsFunction() ) { - callback_required = true; - cbfunc_arg = 1; - } else { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - - Connection *db = ObjectWrap::Unwrap( args.This() ); - - if( db == NULL || db->conn == NULL ) { - std::string error_msg; - getErrorMsg( JS_ERR_NOT_CONNECTED, error_msg ); - callBack( &( error_msg ), args[cbfunc_arg], undef, callback_required ); - args.GetReturnValue().SetUndefined(); - return; + Local undef = Local::New(isolate, Undefined(isolate)); + + if (args.Length() == 1 && args[0]->IsString()) + { + // do nothing + } + else if (args.Length() == 2 && args[0]->IsString() && args[1]->IsFunction()) + { + callback_required = true; + cbfunc_arg = 1; + } + else + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + + Connection *db = ObjectWrap::Unwrap(args.This()); + + if (db == NULL || db->conn == NULL) + { + std::string error_msg; + getErrorMsg(JS_ERR_NOT_CONNECTED, error_msg); + callBack(&(error_msg), args[cbfunc_arg], undef, callback_required); + args.GetReturnValue().SetUndefined(); + return; } Persistent p_stmt; - StmtObject::CreateNewInstance( args, p_stmt ); - Local l_stmt = Local::New( isolate, p_stmt ); - StmtObject *obj = ObjectWrap::Unwrap( l_stmt ); + StmtObject::CreateNewInstance(args, p_stmt); + Local l_stmt = Local::New(isolate, p_stmt); + StmtObject *obj = ObjectWrap::Unwrap(l_stmt); obj->connection = db; { - scoped_lock lock( db->conn_mutex ); - db->statements.push_back( obj ); + scoped_lock lock(db->conn_mutex); + db->statements.push_back(obj); } - if( obj == NULL ) { + if (obj == NULL) + { std::string error_msg; - getErrorMsg( JS_ERR_GENERAL_ERROR, error_msg ); - callBack( &( error_msg ), args[cbfunc_arg], undef, callback_required ); - args.GetReturnValue().SetUndefined(); - p_stmt.Reset(); - return; - } - -#if NODE_MAJOR_VERSION >= 12 - String::Utf8Value param0( isolate, (args[0]->ToString(context)).ToLocalChecked() ); -#else - String::Utf8Value param0( (args[0]->ToString(context)).ToLocalChecked() ); -#endif + getErrorMsg(JS_ERR_GENERAL_ERROR, error_msg); + callBack(&(error_msg), args[cbfunc_arg], undef, callback_required); + args.GetReturnValue().SetUndefined(); + p_stmt.Reset(); + return; + } + + String::Utf8Value param0(isolate, (args[0]->ToString(context)).ToLocalChecked()); prepareBaton *baton = new prepareBaton(); baton->obj = obj; - baton->callback_required = callback_required; - baton->stmt = std::string(*param0); - + baton->callback_required = callback_required; + baton->stmt = std::string(*param0); + uv_work_t *req = new uv_work_t(); req->data = baton; - - if( callback_required ) { - Local callback = Local::Cast(args[cbfunc_arg]); - baton->callback.Reset( isolate, callback ); - baton->StmtObj.Reset( isolate, p_stmt ); - int status; - status = uv_queue_work( uv_default_loop(), req, prepareWork, - (uv_after_work_cb)prepareAfter ); - assert(status == 0); - - args.GetReturnValue().SetUndefined(); - p_stmt.Reset(); - return; - } - - prepareWork( req ); + + if (callback_required) + { + Local callback = Local::Cast(args[cbfunc_arg]); + baton->callback.Reset(isolate, callback); + baton->StmtObj.Reset(isolate, p_stmt); + int status; + status = uv_queue_work(uv_default_loop(), req, prepareWork, + (uv_after_work_cb)prepareAfter); + assert(status == 0); + + args.GetReturnValue().SetUndefined(); + p_stmt.Reset(); + return; + } + + prepareWork(req); bool err = baton->err; - prepareAfter( req ); - - if( err ) { - args.GetReturnValue().SetUndefined(); - return; + prepareAfter(req); + + if (err) + { + args.GetReturnValue().SetUndefined(); + return; } - args.GetReturnValue().Set( p_stmt ); + args.GetReturnValue().Set(p_stmt.Get(isolate)); p_stmt.Reset(); } - // Connect and disconnect // Connect Function -struct connectBaton { - Persistent callback; - bool err; - std::string error_msg; - bool callback_required; - - Connection *obj; - bool sqlca_connection; - std::string conn_string; - void *sqlca; - - connectBaton() { - obj = NULL; - sqlca = NULL; - sqlca_connection = false; - err = false; - callback_required = false; - } - - ~connectBaton() { - obj = NULL; - sqlca = NULL; - callback.Reset(); - } - +struct connectBaton +{ + Persistent callback; + bool err; + std::string error_msg; + bool callback_required; + + Connection *obj; + bool sqlca_connection; + std::string conn_string; + void *sqlca; + + connectBaton() + { + obj = NULL; + sqlca = NULL; + sqlca_connection = false; + err = false; + callback_required = false; + } + + ~connectBaton() + { + obj = NULL; + sqlca = NULL; + callback.Reset(); + } }; -void Connection::connectWork( uv_work_t *req ) +void Connection::connectWork(uv_work_t *req) /*********************************************/ { - connectBaton *baton = static_cast(req->data); - scoped_lock api_lock( api_mutex ); - scoped_lock lock( baton->obj->conn_mutex ); - - if( baton->obj->conn != NULL ) { - baton->err = true; - getErrorMsg( JS_ERR_CONNECTION_ALREADY_EXISTS, baton->error_msg ); - return; - } - - if( api.initialized == false) { - - if( !sqlany_initialize_interface( &api, NULL ) ) { - baton->err = true; - getErrorMsg( JS_ERR_INITIALIZING_DBCAPI, baton->error_msg ); - return; - } - - if( !api.sqlany_init( "Node.js", SQLANY_API_VERSION_4, - &(baton->obj->max_api_ver) )) { - // As long as the version is >= 2, we're OK. We just have to disable - // wide inserts - if( baton->obj->max_api_ver >= SQLANY_API_VERSION_2 ) { - if( !api.sqlany_init( "Node.js", baton->obj->max_api_ver, - &(baton->obj->max_api_ver) )) { - baton->err = true; - getErrorMsg( JS_ERR_INITIALIZING_DBCAPI, baton->error_msg ); - return; - } - } else { - baton->err = true; - getErrorMsg( JS_ERR_INITIALIZING_DBCAPI, baton->error_msg ); - return; - } - } - } - - if( !baton->sqlca_connection ) { - baton->obj->conn = api.sqlany_new_connection(); - if( !api.sqlany_connect( baton->obj->conn, baton->conn_string.c_str() ) ) { - getErrorMsg( baton->obj->conn, baton->error_msg ); - baton->err = true; - api.sqlany_free_connection( baton->obj->conn ); - baton->obj->conn = NULL; - cleanAPI(); - return; - } - - } else { - baton->obj->conn = api.sqlany_make_connection( baton->sqlca ); - if( baton->obj->conn == NULL ) { - getErrorMsg( baton->obj->conn, baton->error_msg ); - cleanAPI(); - return; - } - } - + connectBaton *baton = static_cast(req->data); + scoped_lock api_lock(api_mutex); + scoped_lock lock(baton->obj->conn_mutex); + + if (baton->obj->conn != NULL) + { + baton->err = true; + getErrorMsg(JS_ERR_CONNECTION_ALREADY_EXISTS, baton->error_msg); + return; + } + + if (api.initialized == false) + { + + if (!sqlany_initialize_interface(&api, NULL)) + { + baton->err = true; + getErrorMsg(JS_ERR_INITIALIZING_DBCAPI, baton->error_msg); + return; + } + + if (!api.sqlany_init("Node.js", SQLANY_API_VERSION_4, + &(baton->obj->max_api_ver))) + { + // As long as the version is >= 2, we're OK. We just have to disable + // wide inserts + if (baton->obj->max_api_ver >= SQLANY_API_VERSION_2) + { + if (!api.sqlany_init("Node.js", baton->obj->max_api_ver, + &(baton->obj->max_api_ver))) + { + baton->err = true; + getErrorMsg(JS_ERR_INITIALIZING_DBCAPI, baton->error_msg); + return; + } + } + else + { + baton->err = true; + getErrorMsg(JS_ERR_INITIALIZING_DBCAPI, baton->error_msg); + return; + } + } + } + + if (!baton->sqlca_connection) + { + baton->obj->conn = api.sqlany_new_connection(); + if (!api.sqlany_connect(baton->obj->conn, baton->conn_string.c_str())) + { + getErrorMsg(baton->obj->conn, baton->error_msg); + baton->err = true; + api.sqlany_free_connection(baton->obj->conn); + baton->obj->conn = NULL; + cleanAPI(); + return; + } + } + else + { + baton->obj->conn = api.sqlany_make_connection(baton->sqlca); + if (baton->obj->conn == NULL) + { + getErrorMsg(baton->obj->conn, baton->error_msg); + cleanAPI(); + return; + } + } + baton->obj->sqlca_connection = baton->sqlca_connection; openConnections++; } -void Connection::connectAfter( uv_work_t *req ) +void Connection::connectAfter(uv_work_t *req) /**********************************************/ { Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - connectBaton *baton = static_cast(req->data); - Local undef = Local::New( isolate, Undefined( isolate ) ); - - if( baton->err ) { - callBack( &( baton->error_msg ), baton->callback, undef, - baton->callback_required ); - delete baton; - delete req; - return; - } - - callBack( NULL, baton->callback, undef, baton->callback_required ); - + HandleScope scope(isolate); + connectBaton *baton = static_cast(req->data); + Local undef = Local::New(isolate, Undefined(isolate)); + + if (baton->err) + { + callBack(&(baton->error_msg), baton->callback, undef, + baton->callback_required); + delete baton; + delete req; + return; + } + + callBack(NULL, baton->callback, undef, baton->callback_required); + delete baton; delete req; } -NODE_API_FUNC( Connection::connect ) +NODE_API_FUNC(Connection::connect) /**********************************/ { Isolate *isolate = args.GetIsolate(); Local context = isolate->GetCurrentContext(); - HandleScope scope( isolate ); - int num_args = args.Length(); + HandleScope scope(isolate); + int num_args = args.Length(); Connection *obj; - obj = ObjectWrap::Unwrap( args.This() ); - bool sqlca_connection = false; - bool callback_required = false; - int cbfunc_arg = -1; - bool arg_is_string = true; - bool arg_is_object = false; - - if( num_args == 0 ) { - arg_is_string = false; - - } else if( num_args == 1 && args[0]->IsFunction() ) { - callback_required = true; - cbfunc_arg = 0; - arg_is_string = false; - - } else if( num_args == 1 && args[0]->IsNumber() ){ - sqlca_connection = true; - - } else if( num_args == 1 && args[0]->IsString() ) { - sqlca_connection = false; - - } else if( num_args == 1 && args[0]->IsObject() ) { - sqlca_connection = false; - arg_is_string = false; - arg_is_object = true; - - } else if( num_args == 2 && args[0]->IsNumber() && args[1]->IsFunction() ) { - sqlca_connection = true; - callback_required = true; - cbfunc_arg = 1; - - } else if( num_args == 2 && args[0]->IsString() && args[1]->IsFunction() ) { - sqlca_connection = false; - callback_required = true; - cbfunc_arg = 1; - - } else if( num_args == 2 && args[0]->IsObject() && args[1]->IsFunction() ) { - sqlca_connection = false; - callback_required = true; - cbfunc_arg = 1; - arg_is_string = false; - arg_is_object = true; - - } else if( num_args > 1 ) { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - + obj = ObjectWrap::Unwrap(args.This()); + bool sqlca_connection = false; + bool callback_required = false; + int cbfunc_arg = -1; + bool arg_is_string = true; + bool arg_is_object = false; + + if (num_args == 0) + { + arg_is_string = false; + } + else if (num_args == 1 && args[0]->IsFunction()) + { + callback_required = true; + cbfunc_arg = 0; + arg_is_string = false; + } + else if (num_args == 1 && args[0]->IsNumber()) + { + sqlca_connection = true; + } + else if (num_args == 1 && args[0]->IsString()) + { + sqlca_connection = false; + } + else if (num_args == 1 && args[0]->IsObject()) + { + sqlca_connection = false; + arg_is_string = false; + arg_is_object = true; + } + else if (num_args == 2 && args[0]->IsNumber() && args[1]->IsFunction()) + { + sqlca_connection = true; + callback_required = true; + cbfunc_arg = 1; + } + else if (num_args == 2 && args[0]->IsString() && args[1]->IsFunction()) + { + sqlca_connection = false; + callback_required = true; + cbfunc_arg = 1; + } + else if (num_args == 2 && args[0]->IsObject() && args[1]->IsFunction()) + { + sqlca_connection = false; + callback_required = true; + cbfunc_arg = 1; + arg_is_string = false; + arg_is_object = true; + } + else if (num_args > 1) + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + connectBaton *baton = new connectBaton(); baton->obj = obj; baton->callback_required = callback_required; baton->sqlca_connection = sqlca_connection; - - if( sqlca_connection ) { + + if (sqlca_connection) + { baton->sqlca = (void *)(long)(args[0]->NumberValue(context)).FromJust(); - - } else { - Local localArg = Local::New( isolate, obj->_arg ); - if( localArg->Length() > 0 ) { -#if NODE_MAJOR_VERSION >= 12 - String::Utf8Value param0( isolate, localArg ); -#else - String::Utf8Value param0( localArg ); -#endif - baton->conn_string = std::string(*param0); - } else { - baton->conn_string = std::string(); - } - if( arg_is_string ) { -#if NODE_MAJOR_VERSION >= 12 - String::Utf8Value param0( isolate, (args[0]->ToString(context)).ToLocalChecked()); -#else - String::Utf8Value param0( (args[0]->ToString(context)).ToLocalChecked() ); -#endif - baton->conn_string.append( ";" ); - baton->conn_string.append(*param0); - } else if( arg_is_object ) { - Persistent arg_string; - HashToString( isolate, args[0]->ToObject(isolate), arg_string ); - Local local_arg_string = - Local::New( isolate, arg_string ); -#if NODE_MAJOR_VERSION >= 12 - String::Utf8Value param0( isolate, local_arg_string ); -#else - String::Utf8Value param0( local_arg_string ); -#endif - baton->conn_string.append( ";" ); - baton->conn_string.append(*param0); - arg_string.Reset(); - } - baton->conn_string.append( ";CHARSET='UTF-8'" ); - } - + } + else + { + Local localArg = Local::New(isolate, obj->_arg); + if (localArg->Length() > 0) + { + String::Utf8Value param0(isolate, localArg); + baton->conn_string = std::string(*param0); + } + else + { + baton->conn_string = std::string(); + } + if (arg_is_string) + { + String::Utf8Value param0(isolate, (args[0]->ToString(context)).ToLocalChecked()); + baton->conn_string.append(";"); + baton->conn_string.append(*param0); + } + else if (arg_is_object) + { + Persistent arg_string; + HashToString(isolate, args[0]->ToObject(context).ToLocalChecked(), arg_string); + Local local_arg_string = + Local::New(isolate, arg_string); + String::Utf8Value param0(isolate, local_arg_string); + baton->conn_string.append(";"); + baton->conn_string.append(*param0); + arg_string.Reset(); + } + baton->conn_string.append(";CHARSET='UTF-8'"); + } + uv_work_t *req = new uv_work_t(); req->data = baton; - - if( callback_required ) { - Local callback = Local::Cast(args[cbfunc_arg]); - baton->callback.Reset( isolate, callback ); - - int status; - status = uv_queue_work( uv_default_loop(), req, connectWork, - (uv_after_work_cb)connectAfter ); - assert(status == 0); - args.GetReturnValue().SetUndefined(); - return; - } - - connectWork( req ); - connectAfter( req ); + + if (callback_required) + { + Local callback = Local::Cast(args[cbfunc_arg]); + baton->callback.Reset(isolate, callback); + + int status; + status = uv_queue_work(uv_default_loop(), req, connectWork, + (uv_after_work_cb)connectAfter); + assert(status == 0); + args.GetReturnValue().SetUndefined(); + return; + } + + connectWork(req); + connectAfter(req); args.GetReturnValue().SetUndefined(); return; } // Disconnect Function -void Connection::disconnectWork( uv_work_t *req ) +void Connection::disconnectWork(uv_work_t *req) /************************************************/ { - noParamBaton *baton = static_cast(req->data); - scoped_lock api_lock(api_mutex ); - scoped_lock lock( baton->obj->conn_mutex ); - - if( baton->obj->conn == NULL ) { - getErrorMsg( JS_ERR_NOT_CONNECTED, baton->error_msg ); - return; + noParamBaton *baton = static_cast(req->data); + scoped_lock api_lock(api_mutex); + scoped_lock lock(baton->obj->conn_mutex); + + if (baton->obj->conn == NULL) + { + getErrorMsg(JS_ERR_NOT_CONNECTED, baton->error_msg); + return; } baton->obj->cleanupStmts(); - if( !baton->obj->sqlca_connection ) { - api.sqlany_disconnect( baton->obj->conn ); + if (!baton->obj->sqlca_connection) + { + api.sqlany_disconnect(baton->obj->conn); } - // Must free the connection object or there will be a memory leak - api.sqlany_free_connection( baton->obj->conn ); + // Must free the connection object or there will be a memory leak + api.sqlany_free_connection(baton->obj->conn); baton->obj->conn = NULL; openConnections--; - if( openConnections <= 0 ) { - openConnections = 0; - cleanAPI(); + if (openConnections <= 0) + { + openConnections = 0; + cleanAPI(); } - + return; } -NODE_API_FUNC( Connection::disconnect ) +NODE_API_FUNC(Connection::disconnect) /*************************************/ { Isolate *isolate = args.GetIsolate(); - HandleScope scope( isolate ); + HandleScope scope(isolate); int num_args = args.Length(); bool callback_required = false; int cbfunc_arg = -1; - - if( num_args == 0 ) { - - } else if( num_args == 1 && args[0]->IsFunction() ) { - callback_required = true; - cbfunc_arg = 0; - - } else { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - - Connection *obj = ObjectWrap::Unwrap( args.This() ); + + if (num_args == 0) + { + } + else if (num_args == 1 && args[0]->IsFunction()) + { + callback_required = true; + cbfunc_arg = 0; + } + else + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + + Connection *obj = ObjectWrap::Unwrap(args.This()); noParamBaton *baton = new noParamBaton(); - + baton->callback_required = callback_required; baton->obj = obj; - + uv_work_t *req = new uv_work_t(); req->data = baton; - - if( callback_required ) { - Local callback = Local::Cast(args[cbfunc_arg]); - baton->callback.Reset( isolate, callback ); - - int status; - status = uv_queue_work( uv_default_loop(), req, disconnectWork, - (uv_after_work_cb)noParamAfter ); - assert(status == 0); - - args.GetReturnValue().SetUndefined(); - return; - } - - disconnectWork( req ); - noParamAfter( req ); + + if (callback_required) + { + Local callback = Local::Cast(args[cbfunc_arg]); + baton->callback.Reset(isolate, callback); + + int status; + status = uv_queue_work(uv_default_loop(), req, disconnectWork, + (uv_after_work_cb)noParamAfter); + assert(status == 0); + + args.GetReturnValue().SetUndefined(); + return; + } + + disconnectWork(req); + noParamAfter(req); args.GetReturnValue().SetUndefined(); return; } -void Connection::commitWork( uv_work_t *req ) +void Connection::commitWork(uv_work_t *req) /********************************************/ { - noParamBaton *baton = static_cast(req->data); - scoped_lock lock( baton->obj->conn_mutex ); - - if( baton->obj->conn == NULL ) { - baton->err = true; - getErrorMsg( JS_ERR_NOT_CONNECTED, baton->error_msg ); - return; + noParamBaton *baton = static_cast(req->data); + scoped_lock lock(baton->obj->conn_mutex); + + if (baton->obj->conn == NULL) + { + baton->err = true; + getErrorMsg(JS_ERR_NOT_CONNECTED, baton->error_msg); + return; } - if( !api.sqlany_commit( baton->obj->conn ) ) { - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - return; + if (!api.sqlany_commit(baton->obj->conn)) + { + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + return; } } -NODE_API_FUNC( Connection::commit ) +NODE_API_FUNC(Connection::commit) /*********************************/ { Isolate *isolate = args.GetIsolate(); - HandleScope scope( isolate ); + HandleScope scope(isolate); int num_args = args.Length(); bool callback_required = false; int cbfunc_arg = -1; - - if( num_args == 0 ) { - - } else if( num_args == 1 && args[0]->IsFunction() ) { - callback_required = true; - cbfunc_arg = 0; - - } else { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - - Connection *obj = ObjectWrap::Unwrap( args.This() ); - + + if (num_args == 0) + { + } + else if (num_args == 1 && args[0]->IsFunction()) + { + callback_required = true; + cbfunc_arg = 0; + } + else + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + + Connection *obj = ObjectWrap::Unwrap(args.This()); + noParamBaton *baton = new noParamBaton(); baton->obj = obj; baton->callback_required = callback_required; - + uv_work_t *req = new uv_work_t(); req->data = baton; - - if( callback_required ) { - Local callback = Local::Cast(args[cbfunc_arg]); - baton->callback.Reset( isolate, callback ); - - int status; - status = uv_queue_work( uv_default_loop(), req, commitWork, - (uv_after_work_cb)noParamAfter ); - assert(status == 0); - - args.GetReturnValue().SetUndefined(); - return; - } - - commitWork( req ); - noParamAfter( req ); + + if (callback_required) + { + Local callback = Local::Cast(args[cbfunc_arg]); + baton->callback.Reset(isolate, callback); + + int status; + status = uv_queue_work(uv_default_loop(), req, commitWork, + (uv_after_work_cb)noParamAfter); + assert(status == 0); + + args.GetReturnValue().SetUndefined(); + return; + } + + commitWork(req); + noParamAfter(req); args.GetReturnValue().SetUndefined(); return; } -void Connection::rollbackWork( uv_work_t *req ) +void Connection::rollbackWork(uv_work_t *req) /**********************************************/ { - noParamBaton *baton = static_cast(req->data); - scoped_lock lock( baton->obj->conn_mutex ); + noParamBaton *baton = static_cast(req->data); + scoped_lock lock(baton->obj->conn_mutex); - if( baton->obj->conn == NULL ) { - baton->err = true; - getErrorMsg( JS_ERR_NOT_CONNECTED, baton->error_msg ); - return; + if (baton->obj->conn == NULL) + { + baton->err = true; + getErrorMsg(JS_ERR_NOT_CONNECTED, baton->error_msg); + return; } - if( !api.sqlany_rollback( baton->obj->conn ) ) { - baton->err = true; - getErrorMsg( baton->obj->conn, baton->error_msg ); - return; + if (!api.sqlany_rollback(baton->obj->conn)) + { + baton->err = true; + getErrorMsg(baton->obj->conn, baton->error_msg); + return; } } -NODE_API_FUNC( Connection::rollback ) +NODE_API_FUNC(Connection::rollback) /***********************************/ { Isolate *isolate = args.GetIsolate(); - HandleScope scope( isolate ); + HandleScope scope(isolate); int num_args = args.Length(); bool callback_required = false; int cbfunc_arg = -1; - - if( num_args == 0 ) { - - } else if( num_args == 1 && args[0]->IsFunction() ) { - callback_required = true; - cbfunc_arg = 0; - - } else { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - - Connection *obj = ObjectWrap::Unwrap( args.This() ); + + if (num_args == 0) + { + } + else if (num_args == 1 && args[0]->IsFunction()) + { + callback_required = true; + cbfunc_arg = 0; + } + else + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + + Connection *obj = ObjectWrap::Unwrap(args.This()); noParamBaton *baton = new noParamBaton(); baton->obj = obj; baton->callback_required = callback_required; - + uv_work_t *req = new uv_work_t(); req->data = baton; - - if( callback_required ) { - Local callback = Local::Cast(args[cbfunc_arg]); - baton->callback.Reset( isolate, callback ); - - int status; - status = uv_queue_work( uv_default_loop(), req, rollbackWork, - (uv_after_work_cb)noParamAfter ); - assert(status == 0); - - args.GetReturnValue().SetUndefined(); - return; - } - - rollbackWork( req ); - noParamAfter( req ); + + if (callback_required) + { + Local callback = Local::Cast(args[cbfunc_arg]); + baton->callback.Reset(isolate, callback); + + int status; + status = uv_queue_work(uv_default_loop(), req, rollbackWork, + (uv_after_work_cb)noParamAfter); + assert(status == 0); + + args.GetReturnValue().SetUndefined(); + return; + } + + rollbackWork(req); + noParamAfter(req); args.GetReturnValue().SetUndefined(); return; } -NODE_API_FUNC( Connection::connected ) +NODE_API_FUNC(Connection::connected) /************************************/ { - Connection *obj = ObjectWrap::Unwrap( args.This() ); - args.GetReturnValue().Set( obj->conn == NULL ? false : true ); + Connection *obj = ObjectWrap::Unwrap(args.This()); + args.GetReturnValue().Set(obj->conn == NULL ? false : true); } -struct dropBaton { - Persistent callback; - bool err; - std::string error_msg; - bool callback_required; - - StmtObject *obj; - - dropBaton() { - err = false; - callback_required = false; - obj = NULL; - } - - ~dropBaton() { - obj = NULL; - callback.Reset(); +struct dropBaton +{ + Persistent callback; + bool err; + std::string error_msg; + bool callback_required; + + StmtObject *obj; + + dropBaton() + { + err = false; + callback_required = false; + obj = NULL; + } + + ~dropBaton() + { + obj = NULL; + callback.Reset(); } }; -void StmtObject::dropAfter( uv_work_t *req ) +void StmtObject::dropAfter(uv_work_t *req) /*******************************************/ { Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - dropBaton *baton = static_cast(req->data); - Local undef = Local::New( isolate, Undefined( isolate ) ); - - if( baton->err ) { - callBack( &( baton->error_msg ), baton->callback, undef, - baton->callback_required ); - delete baton; - delete req; - return; - } - - callBack( NULL, baton->callback, undef, baton->callback_required ); - + HandleScope scope(isolate); + dropBaton *baton = static_cast(req->data); + Local undef = Local::New(isolate, Undefined(isolate)); + + if (baton->err) + { + callBack(&(baton->error_msg), baton->callback, undef, + baton->callback_required); + delete baton; + delete req; + return; + } + + callBack(NULL, baton->callback, undef, baton->callback_required); + delete baton; delete req; } -void StmtObject::dropWork( uv_work_t *req ) +void StmtObject::dropWork(uv_work_t *req) /******************************************/ { - dropBaton *baton = static_cast(req->data); - scoped_lock connlock( baton->obj->connection->conn_mutex ); + dropBaton *baton = static_cast(req->data); + scoped_lock connlock(baton->obj->connection->conn_mutex); baton->obj->cleanup(); baton->obj->removeConnection(); } -NODE_API_FUNC( StmtObject::drop ) +NODE_API_FUNC(StmtObject::drop) /*******************************/ { Isolate *isolate = args.GetIsolate(); - HandleScope scope( isolate ); + HandleScope scope(isolate); int num_args = args.Length(); bool callback_required = false; int cbfunc_arg = -1; - - if( num_args == 0 ) { - - } else if( num_args == 1 && args[0]->IsFunction() ) { - callback_required = true; - cbfunc_arg = 0; - - } else { - throwError( JS_ERR_INVALID_ARGUMENTS ); - args.GetReturnValue().SetUndefined(); - return; - } - - StmtObject *obj = ObjectWrap::Unwrap( args.This() ); + + if (num_args == 0) + { + } + else if (num_args == 1 && args[0]->IsFunction()) + { + callback_required = true; + cbfunc_arg = 0; + } + else + { + throwError(JS_ERR_INVALID_ARGUMENTS); + args.GetReturnValue().SetUndefined(); + return; + } + + StmtObject *obj = ObjectWrap::Unwrap(args.This()); dropBaton *baton = new dropBaton(); baton->obj = obj; baton->callback_required = callback_required; - + uv_work_t *req = new uv_work_t(); req->data = baton; - - if( callback_required ) { - Local callback = Local::Cast(args[cbfunc_arg]); - baton->callback.Reset( isolate, callback ); - - int status; - status = uv_queue_work( uv_default_loop(), req, dropWork, - (uv_after_work_cb)dropAfter ); - assert(status == 0); - - args.GetReturnValue().SetUndefined(); - return; - } - - dropWork( req ); - dropAfter( req ); + + if (callback_required) + { + Local callback = Local::Cast(args[cbfunc_arg]); + baton->callback.Reset(isolate, callback); + + int status; + status = uv_queue_work(uv_default_loop(), req, dropWork, + (uv_after_work_cb)dropAfter); + assert(status == 0); + + args.GetReturnValue().SetUndefined(); + return; + } + + dropWork(req); + dropAfter(req); args.GetReturnValue().SetUndefined(); return; } -void init( Local exports ) +void init(Local exports) /********************************/ { uv_mutex_init(&api_mutex); -#if v012 - Isolate *isolate = Isolate::GetCurrent(); -#else Isolate *isolate = exports->GetIsolate(); -#endif - StmtObject::Init( isolate ); - Connection::Init( isolate ); - NODE_SET_METHOD( exports, "createConnection", Connection::NewInstance ); + StmtObject::Init(isolate); + Connection::Init(isolate); + NODE_SET_METHOD(exports, "createConnection", Connection::NewInstance); } -NODE_MODULE( DRIVER_NAME, init ) - -#endif // !v010 +NODE_MODULE(DRIVER_NAME, init) diff --git a/src/utils.cpp b/src/utils.cpp index 841a1d8..90a0de2 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -5,866 +5,898 @@ #include "sqlany_utils.h" #include "nan.h" -#if !v010 - using namespace v8; using namespace node; -void getErrorMsg( int code, std::string &str ) +void getErrorMsg(int code, std::string &str) /********************************************/ { - std::ostringstream message; - message << "Code: "; - message << code; - message << " Msg: "; - - switch( code ) { + std::ostringstream message; + message << "Code: "; + message << code; + message << " Msg: "; + + switch (code) + { case JS_ERR_INVALID_OBJECT: - message << "Invalid Object"; - break; + message << "Invalid Object"; + break; case JS_ERR_INVALID_ARGUMENTS: - message << "Invalid Arguments"; - break; + message << "Invalid Arguments"; + break; case JS_ERR_CONNECTION_ALREADY_EXISTS: - message << "Already Connected"; - break; + message << "Already Connected"; + break; case JS_ERR_INITIALIZING_DBCAPI: - message << "Can't initialize DBCAPI"; - break; + message << "Can't initialize DBCAPI"; + break; case JS_ERR_NOT_CONNECTED: - message << "No Connection Available"; - break; + message << "No Connection Available"; + break; case JS_ERR_BINDING_PARAMETERS: - message << "Can not bind parameter(s)"; - break; + message << "Can not bind parameter(s)"; + break; case JS_ERR_GENERAL_ERROR: - message << "An error occurred"; - break; + message << "An error occurred"; + break; case JS_ERR_RESULTSET: - message << "Error making result set Object"; - break; + message << "Error making result set Object"; + break; case JS_ERR_NO_WIDE_STATEMENTS: - message << "The DBCAPI library must be upgraded to support wide statements"; - break; + message << "The DBCAPI library must be upgraded to support wide statements"; + break; default: - message << "Unknown Error"; - } - str = message.str(); - + message << "Unknown Error"; + } + str = message.str(); } -void getErrorMsg( a_sqlany_connection *conn, std::string &str ) +void getErrorMsg(a_sqlany_connection *conn, std::string &str) /*************************************************************/ { - char buffer[SACAPI_ERROR_SIZE]; - int rc; - rc = api.sqlany_error( conn, buffer, sizeof(buffer) ); - std::ostringstream message; - message << "Code: "; - message << rc; - message << " Msg: "; - message << buffer; - str = message.str(); + char buffer[SACAPI_ERROR_SIZE]; + int rc; + rc = api.sqlany_error(conn, buffer, sizeof(buffer)); + std::ostringstream message; + message << "Code: "; + message << rc; + message << " Msg: "; + message << buffer; + str = message.str(); } -void throwError( a_sqlany_connection *conn ) +void throwError(a_sqlany_connection *conn) /******************************************/ { - Isolate *isolate = Isolate::GetCurrent(); - std::string message; - getErrorMsg( conn, message ); - isolate->ThrowException( - Exception::Error( String::NewFromUtf8( isolate, message.c_str() ) ) ); + Isolate *isolate = Isolate::GetCurrent(); + std::string message; + getErrorMsg(conn, message); + isolate->ThrowException( + Exception::Error(String::NewFromUtf8(isolate, message.c_str()).ToLocalChecked())); } -void throwError( int code ) +void throwError(int code) /*************************/ { - Isolate *isolate = Isolate::GetCurrent(); - std::string message; - getErrorMsg( code, message ); - isolate->ThrowException( - Exception::Error( String::NewFromUtf8( isolate, message.c_str() ) ) ); + Isolate *isolate = Isolate::GetCurrent(); + std::string message; + getErrorMsg(code, message); + isolate->ThrowException( + Exception::Error(String::NewFromUtf8(isolate, message.c_str()).ToLocalChecked())); } -void callBack( std::string * str, - Persistent & callback, - Local & Result, - bool callback_required ) +void callBack(std::string *str, + Persistent &callback, + Local &Result, + bool callback_required) /*********************************************************/ { - Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - Local local_callback = Local::New( isolate, callback ); - - // If string is NULL, then there is no error - if( callback_required ) { - if( !local_callback->IsFunction() ) { - throwError( JS_ERR_INVALID_ARGUMENTS ); - return; - } - - Local Err; - if( str == NULL ) { - Err = Local::New( isolate, Undefined( isolate ) ); - - } else { - Err = Exception::Error( String::NewFromUtf8( isolate, str->c_str() ) ); - } - - int argc = 2; - Local argv[2] = { Err, Result }; - -#if v012 - TryCatch try_catch; -#else - TryCatch try_catch( isolate ); -#endif - Nan::Callback *cb = new Nan::Callback( local_callback ); - Nan::Call( *cb, argc, argv ); - if( try_catch.HasCaught()) { - node::FatalException( isolate, try_catch ); + Isolate *isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + Local local_callback = Local::New(isolate, callback); + + // If string is NULL, then there is no error + if (callback_required) + { + if (!local_callback->IsFunction()) + { + throwError(JS_ERR_INVALID_ARGUMENTS); + return; + } + + Local Err; + if (str == NULL) + { + Err = Local::New(isolate, Undefined(isolate)); + } + else + { + Err = Exception::Error(String::NewFromUtf8(isolate, str->c_str()).ToLocalChecked()); + } + + int argc = 2; + Local argv[2] = {Err, Result}; + + TryCatch try_catch(isolate); + Nan::Callback *cb = new Nan::Callback(local_callback); + Nan::Call(*cb, argc, argv); + if (try_catch.HasCaught()) + { + node::FatalException(isolate, try_catch); + } } - } else { - if( str != NULL ) { - isolate->ThrowException( - Exception::Error( String::NewFromUtf8( isolate, str->c_str() ) ) ); + else + { + if (str != NULL) + { + isolate->ThrowException( + Exception::Error(String::NewFromUtf8(isolate, str->c_str()).ToLocalChecked())); + } } - } } -void callBack( std::string * str, - Persistent & callback, - Persistent & Result, - bool callback_required ) +void callBack(std::string *str, + Persistent &callback, + Persistent &Result, + bool callback_required) /*********************************************************/ { - Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - Local local_result = Local::New( isolate, Result ); + Isolate *isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + Local local_result = Local::New(isolate, Result); - callBack( str, callback, local_result, callback_required ); + callBack(str, callback, local_result, callback_required); } -void callBack( std::string * str, - const Local & arg, - Local & Result, - bool callback_required ) +void callBack(std::string *str, + const Local &arg, + Local &Result, + bool callback_required) /*********************************************************/ { - Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - - // If string is NULL, then there is no error - if( callback_required ) { - if( !arg->IsFunction() ) { - throwError( JS_ERR_INVALID_ARGUMENTS ); - return; - } - Local callback = Local::Cast(arg); - - Local Err; - if( str == NULL ) { - Err = Local::New( isolate, Undefined( isolate ) ); - - } else { - Err = Exception::Error( String::NewFromUtf8( isolate, str->c_str() ) ); - } - - int argc = 2; - Local argv[2] = { Err, Result }; - -#if v012 - TryCatch try_catch; -#else - TryCatch try_catch( isolate ); -#endif - Nan::Callback *cb = new Nan::Callback( callback ); - Nan::Call( *cb, argc, argv ); - if( try_catch.HasCaught()) { - node::FatalException( isolate, try_catch ); + Isolate *isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + + // If string is NULL, then there is no error + if (callback_required) + { + if (!arg->IsFunction()) + { + throwError(JS_ERR_INVALID_ARGUMENTS); + return; + } + Local callback = Local::Cast(arg); + + Local Err; + if (str == NULL) + { + Err = Local::New(isolate, Undefined(isolate)); + } + else + { + Err = Exception::Error(String::NewFromUtf8(isolate, str->c_str()).ToLocalChecked()); + } + + int argc = 2; + Local argv[2] = {Err, Result}; + + TryCatch try_catch(isolate); + Nan::Callback *cb = new Nan::Callback(callback); + Nan::Call(*cb, argc, argv); + if (try_catch.HasCaught()) + { + node::FatalException(isolate, try_catch); + } } - - } else { - if( str != NULL ) { - isolate->ThrowException( - Exception::Error( String::NewFromUtf8( isolate, str->c_str() ) ) ); + else + { + if (str != NULL) + { + isolate->ThrowException( + Exception::Error(String::NewFromUtf8(isolate, str->c_str()).ToLocalChecked())); + } } - } } -static bool getWideBindParameters( std::vector &execData, - Isolate * isolate, - Local arg, - std::vector & params, - unsigned &num_rows ) +static bool getWideBindParameters(std::vector &execData, + Isolate *isolate, + Local arg, + std::vector ¶ms, + unsigned &num_rows) /*********************************************************************************/ { - Local context = isolate->GetCurrentContext(); - Local rows = Local::Cast( arg ); - num_rows = rows->Length(); + Local context = isolate->GetCurrentContext(); + Local rows = Local::Cast(arg); + num_rows = rows->Length(); + + Local row0 = Local::Cast(rows->Get(context, 0).ToLocalChecked()); + unsigned num_cols = row0->Length(); + unsigned c; + + if (num_cols == 0) + { + // if an empty array was passed in, we still need ExecuteData + ExecuteData *ex = new ExecuteData; + execData.push_back(ex); + return true; + } - Local row0 = Local::Cast( rows->Get(0) ); - unsigned num_cols = row0->Length(); - unsigned c; + // Make sure that each array in the list has the same number and types + // of values + for (unsigned int r = 1; r < num_rows; r++) + { + Local row = Local::Cast(rows->Get(context, r).ToLocalChecked()); + for (c = 0; c < num_cols; c++) + { + Local val0 = row0->Get(context, c).ToLocalChecked(); + Local val = row->Get(context, c).ToLocalChecked(); + + if ((val0->IsInt32() || val0->IsNumber()) && + (!val->IsInt32() && !val->IsNumber() && !val->IsNull())) + { + return false; + } + if (val0->IsString() && + !val->IsString() && !val->IsNull()) + { + return false; + } + if (Buffer::HasInstance(val0) && + !Buffer::HasInstance(val) && !val->IsNull()) + { + return false; + } + } + } - if( num_cols == 0 ) { - // if an empty array was passed in, we still need ExecuteData - ExecuteData *ex = new ExecuteData; - execData.push_back( ex ); - return true; - } + for (c = 0; c < num_cols; c++) + { + a_sqlany_bind_param param; + memset(¶m, 0, sizeof(param)); + + ExecuteData *ex = new ExecuteData; + execData.push_back(ex); + + double *param_double = new double[num_rows]; + ex->addNum(param_double); + char **char_arr = new char *[num_rows]; + size_t *len = new size_t[num_rows]; + ex->addStrings(char_arr, len); + sacapi_bool *is_null = new sacapi_bool[num_rows]; + ex->addNull(is_null); + param.value.is_null = is_null; + param.value.is_address = false; + + if (row0->Get(context, c).ToLocalChecked()->IsInt32() || row0->Get(context, c).ToLocalChecked()->IsNumber()) + { + param.value.type = A_DOUBLE; + param.value.buffer = (char *)(param_double); + } + else if (row0->Get(context, c).ToLocalChecked()->IsString()) + { + param.value.type = A_STRING; + param.value.buffer = (char *)char_arr; + param.value.length = len; + param.value.is_address = true; + } + else if (Buffer::HasInstance(row0->Get(context, c).ToLocalChecked())) + { + param.value.type = A_BINARY; + param.value.buffer = (char *)char_arr; + param.value.length = len; + param.value.is_address = true; + } + else if (row0->Get(context, c).ToLocalChecked()->IsNull()) + { + } + else + { + return false; + } - // Make sure that each array in the list has the same number and types - // of values - for( unsigned int r = 1; r < num_rows; r++ ) { - Local row = Local::Cast( rows->Get(r) ); - for( c = 0; c < num_cols; c++ ) { - Local val0 = row0->Get(c); - Local val = row->Get(c); - - if( ( val0->IsInt32() || val0->IsNumber() ) && - ( !val->IsInt32() && !val->IsNumber() && !val->IsNull() ) ) { - return false; - } - if( val0->IsString() && - !val->IsString() && !val->IsNull() ) { - return false; - } - if( Buffer::HasInstance( val0 ) && - !Buffer::HasInstance( val ) && !val->IsNull() ) { - return false; - } - } - } + for (unsigned int r = 0; r < num_rows; r++) + { + Local bind_params = Local::Cast(rows->Get(context, r).ToLocalChecked()); - for( c = 0; c < num_cols; c++ ) { - a_sqlany_bind_param param; - memset( ¶m, 0, sizeof( param ) ); + is_null[r] = false; + if (bind_params->Get(context, c).ToLocalChecked()->IsInt32() || bind_params->Get(context, c).ToLocalChecked()->IsNumber()) + { + param_double[r] = bind_params->Get(context, c).ToLocalChecked()->NumberValue(context).FromJust(); + } + else if (bind_params->Get(context, c).ToLocalChecked()->IsString()) + { + String::Utf8Value paramValue(isolate, (bind_params->Get(context, c).ToLocalChecked()->ToString(context)).ToLocalChecked()); + const char *param_string = (*paramValue); + len[r] = (size_t)paramValue.length(); + char *param_char = new char[len[r] + 1]; + char_arr[r] = param_char; + memcpy(param_char, param_string, len[r] + 1); + } + else if (Buffer::HasInstance(bind_params->Get(context, c).ToLocalChecked())) + { + len[r] = Buffer::Length(bind_params->Get(context, c).ToLocalChecked()); + char *param_char = new char[len[r]]; + char_arr[r] = param_char; + memcpy(param_char, Buffer::Data(bind_params->Get(context, c).ToLocalChecked()), len[r]); + } + else if (bind_params->Get(context, c).ToLocalChecked()->IsNull()) + { + is_null[r] = true; + } + } - ExecuteData *ex = new ExecuteData; - execData.push_back( ex ); - - double * param_double = new double[num_rows]; - ex->addNum( param_double ); - char ** char_arr = new char *[num_rows]; - size_t * len = new size_t[num_rows]; - ex->addStrings( char_arr, len ); - sacapi_bool * is_null = new sacapi_bool[num_rows]; - ex->addNull( is_null ); - param.value.is_null = is_null; - param.value.is_address = false; - - if( row0->Get(c)->IsInt32() || row0->Get(c)->IsNumber() ) { - param.value.type = A_DOUBLE; - param.value.buffer = (char *)( param_double ); - - } else if( row0->Get(c)->IsString() ) { - param.value.type = A_STRING; - param.value.buffer = (char *)char_arr; - param.value.length = len; - param.value.is_address = true; - - } else if( Buffer::HasInstance( row0->Get(c) ) ) { - param.value.type = A_BINARY; - param.value.buffer = (char *)char_arr; - param.value.length = len; - param.value.is_address = true; - - } else if( row0->Get(c)->IsNull() ) { - - } else{ - return false; + params.push_back(param); } - for( unsigned int r = 0; r < num_rows; r++ ) { - Local bind_params = Local::Cast( rows->Get(r) ); - - is_null[r] = false; - if( bind_params->Get(c)->IsInt32() || bind_params->Get(c)->IsNumber() ) { - param_double[r] = bind_params->Get(c)->NumberValue(context).FromJust(); - - } else if( bind_params->Get(c)->IsString() ) { -#if NODE_MAJOR_VERSION >= 12 - String::Utf8Value paramValue( isolate, (bind_params->Get(c)->ToString(context)).ToLocalChecked() ); -#else - String::Utf8Value paramValue( (bind_params->Get(c)->ToString(context)).ToLocalChecked() ); -#endif - const char* param_string = (*paramValue); - len[r] = (size_t)paramValue.length(); - char *param_char = new char[len[r] + 1]; - char_arr[r] = param_char; - memcpy( param_char, param_string, len[r] + 1 ); - - } else if( Buffer::HasInstance( bind_params->Get(c) ) ) { - len[r] = Buffer::Length( bind_params->Get(c) ); - char *param_char = new char[len[r]]; - char_arr[r] = param_char; - memcpy( param_char, Buffer::Data( bind_params->Get(c) ), len[r] ); - - } else if( bind_params->Get(c)->IsNull() ) { - is_null[r] = true; - } - } - - params.push_back( param ); - } - - return true; + return true; } -bool getBindParameters( std::vector &execData, - Isolate * isolate, - Local arg, - std::vector & params, - unsigned &num_rows ) +bool getBindParameters(std::vector &execData, + Isolate *isolate, + Local arg, + std::vector ¶ms, + unsigned &num_rows) /*************************************************************************/ { - Local context = isolate->GetCurrentContext(); - Local bind_params = Local::Cast( arg ); + Local context = isolate->GetCurrentContext(); + Local bind_params = Local::Cast(arg); + + if (bind_params->Length() == 0) + { + // if an empty array was passed in, we still need ExecuteData + ExecuteData *ex = new ExecuteData; + execData.push_back(ex); + return true; + } + + if (bind_params->Get(context, 0).ToLocalChecked()->IsArray()) + { + return getWideBindParameters(execData, isolate, arg, params, num_rows); + } + num_rows = 1; - if( bind_params->Length() == 0 ) { - // if an empty array was passed in, we still need ExecuteData ExecuteData *ex = new ExecuteData; - execData.push_back( ex ); - return true; - } + execData.push_back(ex); + + for (unsigned int i = 0; i < bind_params->Length(); i++) + { + a_sqlany_bind_param param; + memset(¶m, 0, sizeof(param)); + + if (bind_params->Get(context, i).ToLocalChecked()->IsInt32()) + { + int *param_int = new int; + *param_int = bind_params->Get(context, i).ToLocalChecked()->Int32Value(context).FromJust(); + ex->addInt(param_int); + param.value.buffer = (char *)(param_int); + param.value.type = A_VAL32; + } + else if (bind_params->Get(context, i).ToLocalChecked()->IsNumber()) + { + double *param_double = new double; + *param_double = bind_params->Get(context, i).ToLocalChecked()->NumberValue(context).FromJust(); // Remove Round off Error + ex->addNum(param_double); + param.value.buffer = (char *)(param_double); + param.value.type = A_DOUBLE; + } + else if (bind_params->Get(context, i).ToLocalChecked()->IsString()) + { + String::Utf8Value paramValue(isolate, (bind_params->Get(context, i).ToLocalChecked()->ToString(context)).ToLocalChecked()); + const char *param_string = (*paramValue); + size_t *len = new size_t; + *len = (size_t)paramValue.length(); + + char **char_arr = new char *; + char *param_char = new char[*len + 1]; + *char_arr = param_char; + + memcpy(param_char, param_string, (*len) + 1); + ex->addStrings(char_arr, len); + + param.value.type = A_STRING; + param.value.buffer = param_char; + param.value.length = len; + param.value.buffer_size = *len + 1; + } + else if (Buffer::HasInstance(bind_params->Get(context, i).ToLocalChecked())) + { + size_t *len = new size_t; + *len = Buffer::Length(bind_params->Get(context, i).ToLocalChecked()); + char **char_arr = new char *; + char *param_char = new char[*len]; + *char_arr = param_char; + + memcpy(param_char, Buffer::Data(bind_params->Get(context, i).ToLocalChecked()), *len); + ex->addStrings(char_arr, len); + + param.value.type = A_BINARY; + param.value.buffer = param_char; + param.value.length = len; + param.value.buffer_size = sizeof(param_char); + } + else if (bind_params->Get(context, i).ToLocalChecked()->IsNull()) + { + param.value.type = A_STRING; + sacapi_bool *is_null = new sacapi_bool; + param.value.is_null = is_null; + ex->addNull(is_null); + is_null[0] = true; + } + else + { + return false; + } - if( bind_params->Get(0)->IsArray() ) { - return getWideBindParameters( execData, isolate, arg, params, num_rows ); - } - num_rows = 1; - - ExecuteData *ex = new ExecuteData; - execData.push_back( ex ); - - for( unsigned int i = 0; i < bind_params->Length(); i++ ) { - a_sqlany_bind_param param; - memset( ¶m, 0, sizeof( param ) ); - - if( bind_params->Get(i)->IsInt32() ) { - int *param_int = new int; - *param_int = bind_params->Get(i)->Int32Value(context).FromJust(); - ex->addInt( param_int ); - param.value.buffer = (char *)( param_int ); - param.value.type = A_VAL32; - - } else if( bind_params->Get(i)->IsNumber() ) { - double *param_double = new double; - *param_double = bind_params->Get(i)->NumberValue(context).FromJust(); // Remove Round off Error - ex->addNum( param_double ); - param.value.buffer = (char *)( param_double ); - param.value.type = A_DOUBLE; - - } else if( bind_params->Get(i)->IsString() ) { -#if NODE_MAJOR_VERSION >= 12 - String::Utf8Value paramValue( isolate, (bind_params->Get(i)->ToString(context)).ToLocalChecked() ); -#else - String::Utf8Value paramValue( (bind_params->Get(i)->ToString(context)).ToLocalChecked() ); -#endif - const char* param_string = (*paramValue); - size_t *len = new size_t; - *len = (size_t)paramValue.length(); - - char **char_arr = new char *; - char *param_char = new char[*len + 1]; - *char_arr = param_char; - - memcpy( param_char, param_string, ( *len ) + 1 ); - ex->addStrings( char_arr, len ); - - param.value.type = A_STRING; - param.value.buffer = param_char; - param.value.length = len; - param.value.buffer_size = *len + 1; - - } else if( Buffer::HasInstance( bind_params->Get(i) ) ) { - size_t *len = new size_t; - *len = Buffer::Length( bind_params->Get(i) ); - char **char_arr = new char *; - char *param_char = new char[*len]; - *char_arr = param_char; - - memcpy( param_char, Buffer::Data( bind_params->Get(i) ), *len ); - ex->addStrings( char_arr, len ); - - param.value.type = A_BINARY; - param.value.buffer = param_char; - param.value.length = len; - param.value.buffer_size = sizeof( param_char ); - - } else if( bind_params->Get(i)->IsNull() ) { - param.value.type = A_STRING; - sacapi_bool *is_null = new sacapi_bool; - param.value.is_null = is_null; - ex->addNull( is_null ); - is_null[0] = true; - - } else{ - return false; + params.push_back(param); } - - params.push_back( param ); - } - return true; + return true; } -bool getResultSet( Persistent & Result, - int & rows_affected, - std::vector & colNames, - ExecuteData * execData, - std::vector & col_types ) +bool getResultSet(Persistent &Result, + int &rows_affected, + std::vector &colNames, + ExecuteData *execData, + std::vector &col_types) /*****************************************************************/ { - Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope( isolate ); - int num_rows = 0; - size_t num_cols = colNames.size(); + Isolate *isolate = Isolate::GetCurrent(); + Local context = isolate->GetCurrentContext(); + HandleScope scope(isolate); + int num_rows = 0; + size_t num_cols = colNames.size(); + + if (rows_affected >= 0) + { + Result.Reset(isolate, Integer::New(isolate, rows_affected)); + return true; + } - if( rows_affected >= 0 ) { - Result.Reset( isolate, Integer::New( isolate, rows_affected ) ); - return true; - } - - if( num_cols > 0 ) { - size_t count = 0; - size_t count_int = 0, count_num = 0, count_string = 0; - Local ResultSet = Array::New( isolate ); - while( count_int < execData->intSize() || - count_num < execData->numSize() || - count_string < execData->stringSize() ) { - Local curr_row = Object::New( isolate ); - num_rows++; - for( size_t i = 0; i < num_cols; i++ ) { - switch( col_types[count] ) { - case A_INVALID_TYPE: - curr_row->Set( String::NewFromUtf8( isolate, colNames[i] ), - Null( isolate ) ); - break; - - case A_VAL32: - case A_VAL16: - case A_UVAL16: - case A_VAL8: - case A_UVAL8: - if( execData->intIsNull( count_int ) ) { - curr_row->Set( String::NewFromUtf8( isolate, colNames[i] ), - Null( isolate ) ); - } else { - curr_row->Set( String::NewFromUtf8( isolate, colNames[i] ), - Integer::New( isolate, execData->getInt( count_int ) ) ); - } - count_int++; - break; - - case A_UVAL32: - case A_UVAL64: - case A_VAL64: - case A_DOUBLE: - if( execData->numIsNull( count_num ) ) { - curr_row->Set( String::NewFromUtf8( isolate, colNames[i] ), - Null( isolate ) ); - } else { - curr_row->Set( String::NewFromUtf8( isolate, colNames[i] ), - Number::New( isolate, execData->getNum( count_num ) ) ); - } - count_num++; - break; - - case A_BINARY: - if( execData->stringIsNull( count_string ) ) { - curr_row->Set( String::NewFromUtf8( isolate, colNames[i] ), - Null( isolate ) ); - } else { -#if v012 - Local buf = node::Buffer::New( - isolate, execData->getString( count_string ), - execData->getLen( count_string ) ); - curr_row->Set( String::NewFromUtf8( isolate, - colNames[i] ), - buf ); -#else - MaybeLocal mbuf = node::Buffer::Copy( - isolate, execData->getString( count_string ), - execData->getLen( count_string ) ); - Local buf = mbuf.ToLocalChecked(); -#endif - curr_row->Set( String::NewFromUtf8( isolate, - colNames[i] ), - buf ); + if (num_cols > 0) + { + size_t count = 0; + size_t count_int = 0, count_num = 0, count_string = 0; + Local ResultSet = Array::New(isolate); + while (count_int < execData->intSize() || + count_num < execData->numSize() || + count_string < execData->stringSize()) + { + Local curr_row = Object::New(isolate); + num_rows++; + for (size_t i = 0; i < num_cols; i++) + { + switch (col_types[count]) + { + case A_INVALID_TYPE: + curr_row->Set(context, String::NewFromUtf8(isolate, colNames[i]).ToLocalChecked(), + Null(isolate)); + break; + + case A_VAL32: + case A_VAL16: + case A_UVAL16: + case A_VAL8: + case A_UVAL8: + if (execData->intIsNull(count_int)) + { + curr_row->Set(context, String::NewFromUtf8(isolate, colNames[i]).ToLocalChecked(), + Null(isolate)); + } + else + { + curr_row->Set(context, String::NewFromUtf8(isolate, colNames[i]).ToLocalChecked(), + Integer::New(isolate, execData->getInt(count_int))); + } + count_int++; + break; + + case A_UVAL32: + case A_UVAL64: + case A_VAL64: + case A_DOUBLE: + if (execData->numIsNull(count_num)) + { + curr_row->Set(context, String::NewFromUtf8(isolate, colNames[i]).ToLocalChecked(), + Null(isolate)); + } + else + { + curr_row->Set(context, String::NewFromUtf8(isolate, colNames[i]).ToLocalChecked(), + Number::New(isolate, execData->getNum(count_num))); + } + count_num++; + break; + + case A_BINARY: + if (execData->stringIsNull(count_string)) + { + curr_row->Set(context, String::NewFromUtf8(isolate, colNames[i]).ToLocalChecked(), + Null(isolate)); + } + else + { + + MaybeLocal mbuf = node::Buffer::Copy( + isolate, execData->getString(count_string), + execData->getLen(count_string)); + Local buf = mbuf.ToLocalChecked(); + curr_row->Set(context, String::NewFromUtf8(isolate, colNames[i]).ToLocalChecked(), + buf); + } + count_string++; + break; + + case A_STRING: + if (execData->stringIsNull(count_string)) + { + curr_row->Set(context, String::NewFromUtf8(isolate, colNames[i]).ToLocalChecked(), + Null(isolate)); + } + else + { + curr_row->Set(context, String::NewFromUtf8(isolate, colNames[i]).ToLocalChecked(), + String::NewFromUtf8(isolate, + execData->getString(count_string), + NewStringType::kNormal, + (int)execData->getLen(count_string)) + .ToLocalChecked()); + } + count_string++; + break; + + default: + return false; + } + count++; } - count_string++; - break; - - case A_STRING: - if( execData->stringIsNull( count_string ) ) { - curr_row->Set( String::NewFromUtf8( isolate, colNames[i] ), - Null( isolate ) ); - } else { - curr_row->Set( String::NewFromUtf8( isolate, - colNames[i] ), -#if v012 - String::NewFromUtf8( isolate, - execData->getString( count_string ), - String::NewStringType::kNormalString, - (int)execData->getLen( count_string ) ) -#else - String::NewFromUtf8( isolate, - execData->getString( count_string ), - NewStringType::kNormal, - (int)execData->getLen( count_string ) ).ToLocalChecked() -#endif - ); - } - count_string++; - break; - - default: - return false; + ResultSet->Set(context, num_rows - 1, curr_row); } - count++; - } - ResultSet->Set( num_rows - 1, curr_row ); + Result.Reset(isolate, ResultSet); } - Result.Reset( isolate, ResultSet ); - } else { - Result.Reset( isolate, Local::New( isolate, - Undefined( isolate ) ) ); - } - - return true; + else + { + Result.Reset(isolate, Local::New(isolate, + Undefined(isolate))); + } + + return true; } -bool fetchResultSet( a_sqlany_stmt * sqlany_stmt, - int & rows_affected, - std::vector & colNames, - ExecuteData * execData, - std::vector & col_types ) +bool fetchResultSet(a_sqlany_stmt *sqlany_stmt, + int &rows_affected, + std::vector &colNames, + ExecuteData *execData, + std::vector &col_types) /*****************************************************************/ { - - a_sqlany_data_value value; - int num_cols = 0; - - rows_affected = api.sqlany_affected_rows( sqlany_stmt ); - num_cols = api.sqlany_num_cols( sqlany_stmt ); - - - if( rows_affected > 0 && num_cols < 1 ) { - return true; - } - - rows_affected = -1; - if( num_cols > 0 ) { - - for( int i = 0; i < num_cols; i++ ) { - a_sqlany_column_info info; - api.sqlany_get_column_info( sqlany_stmt, i, &info ); - size_t size = strlen( info.name ) + 1; - char *name = new char[ size ]; - memcpy( name, info.name, size ); - colNames.push_back( name ); - } - - int count_string = 0, count_num = 0, count_int = 0; - while( api.sqlany_fetch_next( sqlany_stmt ) ) { - for( int i = 0; i < num_cols; i++ ) { + a_sqlany_data_value value; + int num_cols = 0; - if( !api.sqlany_get_column( sqlany_stmt, i, &value ) ) { - return false; - break; - } - - if( *(value.is_null) ) { - col_types.push_back( A_INVALID_TYPE ); - continue; + rows_affected = api.sqlany_affected_rows(sqlany_stmt); + num_cols = api.sqlany_num_cols(sqlany_stmt); + + if (rows_affected > 0 && num_cols < 1) + { + return true; + } + + rows_affected = -1; + if (num_cols > 0) + { + + for (int i = 0; i < num_cols; i++) + { + a_sqlany_column_info info; + api.sqlany_get_column_info(sqlany_stmt, i, &info); + size_t size = strlen(info.name) + 1; + char *name = new char[size]; + memcpy(name, info.name, size); + colNames.push_back(name); } - - switch( value.type ) { - case A_BINARY: - { - size_t *size = new size_t; - *size = *(value.length); - char *val = new char[ *size ]; - memcpy( val, value.buffer, *size ); - execData->addString( val, size ); - count_string++; - break; - } - - case A_STRING: - { - size_t *size = new size_t; - *size = (size_t)( (int)*(value.length) ); - char *val = new char[ *size ]; - memcpy( val, (char *)value.buffer, *size ); - execData->addString( val, size ); - count_string++; - break; - } - - case A_VAL64: - { - double *val = new double; - *val = (double)*(long long *)value.buffer; - execData->addNum( val ); - count_num++; - break; - } - - case A_UVAL64: - { - double *val = new double; - *val = (double)*(unsigned long long *)value.buffer; - execData->addNum( val ); - count_num++; - break; - } - - case A_VAL32: - { - int *val = new int; - *val = *(int*)value.buffer; - execData->addInt( val ); - count_int++; - break; - } - - case A_UVAL32: - { - double *val = new double; - *val = (double)*(unsigned int*)value.buffer; - execData->addNum( val ); - count_num++; - break; - } - - case A_VAL16: - { - int *val = new int; - *val = (int)*(short*)value.buffer; - execData->addInt( val ); - count_int++; - break; - } - - case A_UVAL16: - { - int *val = new int; - *val = (int)*(unsigned short*)value.buffer; - execData->addInt( val ); - count_int++; - break; - } - - case A_VAL8: - { - int *val = new int; - *val = (int)*(char *)value.buffer; - execData->addInt( val ); - count_int++; - break; - } - - case A_UVAL8: - { - int *val = new int; - *val = (int)*(unsigned char *)value.buffer; - execData->addInt( val ); - count_int++; - break; - } - - case A_DOUBLE: - { - double *val = new double; - *val = (double)*(double *)value.buffer; - execData->addNum( val ); - count_num++; - break; - } - - default: - return false; + + int count_string = 0, count_num = 0, count_int = 0; + while (api.sqlany_fetch_next(sqlany_stmt)) + { + + for (int i = 0; i < num_cols; i++) + { + + if (!api.sqlany_get_column(sqlany_stmt, i, &value)) + { + return false; + break; + } + + if (*(value.is_null)) + { + col_types.push_back(A_INVALID_TYPE); + continue; + } + + switch (value.type) + { + case A_BINARY: + { + size_t *size = new size_t; + *size = *(value.length); + char *val = new char[*size]; + memcpy(val, value.buffer, *size); + execData->addString(val, size); + count_string++; + break; + } + + case A_STRING: + { + size_t *size = new size_t; + *size = (size_t)((int)*(value.length)); + char *val = new char[*size]; + memcpy(val, (char *)value.buffer, *size); + execData->addString(val, size); + count_string++; + break; + } + + case A_VAL64: + { + double *val = new double; + *val = (double)*(long long *)value.buffer; + execData->addNum(val); + count_num++; + break; + } + + case A_UVAL64: + { + double *val = new double; + *val = (double)*(unsigned long long *)value.buffer; + execData->addNum(val); + count_num++; + break; + } + + case A_VAL32: + { + int *val = new int; + *val = *(int *)value.buffer; + execData->addInt(val); + count_int++; + break; + } + + case A_UVAL32: + { + double *val = new double; + *val = (double)*(unsigned int *)value.buffer; + execData->addNum(val); + count_num++; + break; + } + + case A_VAL16: + { + int *val = new int; + *val = (int)*(short *)value.buffer; + execData->addInt(val); + count_int++; + break; + } + + case A_UVAL16: + { + int *val = new int; + *val = (int)*(unsigned short *)value.buffer; + execData->addInt(val); + count_int++; + break; + } + + case A_VAL8: + { + int *val = new int; + *val = (int)*(char *)value.buffer; + execData->addInt(val); + count_int++; + break; + } + + case A_UVAL8: + { + int *val = new int; + *val = (int)*(unsigned char *)value.buffer; + execData->addInt(val); + count_int++; + break; + } + + case A_DOUBLE: + { + double *val = new double; + *val = (double)*(double *)value.buffer; + execData->addNum(val); + count_num++; + break; + } + + default: + return false; + } + col_types.push_back(value.type); + } } - col_types.push_back( value.type ); - } } - } - - return true; + + return true; } bool cleanAPI() /*************/ { - if( openConnections == 0 ) { - if( api.initialized ) { - api.sqlany_fini(); - sqlany_finalize_interface( &api ); - return true; + if (openConnections == 0) + { + if (api.initialized) + { + api.sqlany_fini(); + sqlany_finalize_interface(&api); + return true; + } } - } - return false; + return false; } // Generic Baton and Callback (After) Function // Use this if the function does not have any return values and -// Does not take any parameters. +// Does not take any parameters. // Create custom Baton and Callback (After) functions otherwise -void Connection::noParamAfter( uv_work_t *req ) +void Connection::noParamAfter(uv_work_t *req) /*********************************************/ { - Isolate *isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); - noParamBaton *baton = static_cast(req->data); - Local undef = Local::New( isolate, Undefined( isolate ) ); - - if( baton->err ) { - callBack( &( baton->error_msg ), baton->callback, undef, - baton->callback_required ); - return; - } - - callBack( NULL, baton->callback, undef, baton->callback_required ); - - delete baton; - delete req; -} + Isolate *isolate = Isolate::GetCurrent(); + HandleScope scope(isolate); + noParamBaton *baton = static_cast(req->data); + Local undef = Local::New(isolate, Undefined(isolate)); + + if (baton->err) + { + callBack(&(baton->error_msg), baton->callback, undef, + baton->callback_required); + return; + } + + callBack(NULL, baton->callback, undef, baton->callback_required); + delete baton; + delete req; +} // Stmt Object Functions StmtObject::StmtObject() /**********************/ { - connection = NULL; - sqlany_stmt = NULL; + connection = NULL; + sqlany_stmt = NULL; } StmtObject::~StmtObject() /***********************/ { - uv_mutex_t *mutex = NULL; - if( connection != NULL ) { - mutex = &connection->conn_mutex; - uv_mutex_lock( mutex ); - } + uv_mutex_t *mutex = NULL; + if (connection != NULL) + { + mutex = &connection->conn_mutex; + uv_mutex_lock(mutex); + } - cleanup(); - removeConnection(); + cleanup(); + removeConnection(); - if( mutex != NULL ) { - uv_mutex_unlock( mutex ); - } + if (mutex != NULL) + { + uv_mutex_unlock(mutex); + } } Persistent StmtObject::constructor; -void StmtObject::Init( Isolate *isolate ) +void StmtObject::Init(Isolate *isolate) /***************************************/ { - HandleScope scope(isolate); - // Prepare constructor template - Local tpl = FunctionTemplate::New( isolate, New ); - tpl->SetClassName( String::NewFromUtf8( isolate, "StmtObject" ) ); - tpl->InstanceTemplate()->SetInternalFieldCount( 1 ); - - // Prototype - NODE_SET_PROTOTYPE_METHOD( tpl, "exec", exec ); - NODE_SET_PROTOTYPE_METHOD( tpl, "drop", drop ); - NODE_SET_PROTOTYPE_METHOD( tpl, "getMoreResults", getMoreResults ); - Local context = isolate->GetCurrentContext(); - constructor.Reset( isolate, tpl->GetFunction( context ).ToLocalChecked() ); + HandleScope scope(isolate); + // Prepare constructor template + Local tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "StmtObject").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + NODE_SET_PROTOTYPE_METHOD(tpl, "exec", exec); + NODE_SET_PROTOTYPE_METHOD(tpl, "drop", drop); + NODE_SET_PROTOTYPE_METHOD(tpl, "getMoreResults", getMoreResults); + Local context = isolate->GetCurrentContext(); + constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); } -void StmtObject::New( const FunctionCallbackInfo &args ) +void StmtObject::New(const FunctionCallbackInfo &args) /*************************************************************/ { - StmtObject* obj = new StmtObject(); + StmtObject *obj = new StmtObject(); - obj->Wrap( args.This() ); - args.GetReturnValue().Set( args.This() ); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); } -void StmtObject::NewInstance( const FunctionCallbackInfo &args ) +void StmtObject::NewInstance(const FunctionCallbackInfo &args) /*********************************************************************/ { - Persistent obj; - CreateNewInstance( args, obj ); - args.GetReturnValue().Set( obj ); + Isolate *isolate = Isolate::GetCurrent(); + Persistent obj; + CreateNewInstance(args, obj); + args.GetReturnValue().Set(obj.Get(isolate)); } -void StmtObject::CreateNewInstance( const FunctionCallbackInfo & args, - Persistent & obj ) +void StmtObject::CreateNewInstance(const FunctionCallbackInfo &args, + Persistent &obj) /***************************************************************************/ { - Isolate *isolate = args.GetIsolate(); - HandleScope scope(isolate); - const unsigned argc = 1; - Local argv[argc] = { args[0] }; - Localcons = Local::New( isolate, constructor ); -#if NODE_MAJOR_VERSION >= 10 - Local env = isolate->GetCurrentContext(); - MaybeLocal mlObj = cons->NewInstance( env, argc, argv ); - Local instance = mlObj.ToLocalChecked(); - - obj.Reset( isolate, instance ); -#else - obj.Reset( isolate, cons->NewInstance( argc, argv ) ); -#endif + Isolate *isolate = args.GetIsolate(); + HandleScope scope(isolate); + const unsigned argc = 1; + Local argv[argc] = {args[0]}; + Local cons = Local::New(isolate, constructor); + Local env = isolate->GetCurrentContext(); + MaybeLocal mlObj = cons->NewInstance(env, argc, argv); + Local instance = mlObj.ToLocalChecked(); + obj.Reset(isolate, instance); } -void StmtObject::cleanup( void ) +void StmtObject::cleanup(void) /******************************/ { - if( sqlany_stmt != NULL ) { - api.sqlany_free_stmt( sqlany_stmt ); - sqlany_stmt = NULL; - } + if (sqlany_stmt != NULL) + { + api.sqlany_free_stmt(sqlany_stmt); + sqlany_stmt = NULL; + } } -void StmtObject::removeConnection( void ) +void StmtObject::removeConnection(void) /***************************************/ { - if( connection != NULL ) { - connection->removeStmt( this ); - connection = NULL; - } + if (connection != NULL) + { + connection->removeStmt(this); + connection = NULL; + } } // Connection Functions -void HashToString( Isolate *isolate, Local obj, Persistent &ret ) +void HashToString(Isolate *isolate, Local obj, Persistent &ret) /*************************************************************/ { - Local context = isolate->GetCurrentContext(); - HandleScope scope(isolate); - Local props = (obj->GetOwnPropertyNames(context)).ToLocalChecked(); - int length = props->Length(); - std::string params = ""; - bool first = true; - for( int i = 0; i < length; i++ ) { - Local key = props->Get(i).As(); - Local val = obj->Get(key).As(); -#if NODE_MAJOR_VERSION >= 12 - String::Utf8Value key_utf8( isolate, key ); - String::Utf8Value val_utf8( isolate, val ); -#else - String::Utf8Value key_utf8( key ); - String::Utf8Value val_utf8( val ); -#endif - if( !first ) { - params += ";"; + Local context = isolate->GetCurrentContext(); + HandleScope scope(isolate); + Local props = (obj->GetOwnPropertyNames(context)).ToLocalChecked(); + int length = props->Length(); + std::string params = ""; + bool first = true; + for (int i = 0; i < length; i++) + { + Local key = props->Get(context, i).ToLocalChecked().As(); + Local val = obj->Get(context, key).ToLocalChecked().As(); + String::Utf8Value key_utf8(isolate, key); + String::Utf8Value val_utf8(isolate, val); + if (!first) + { + params += ";"; + } + first = false; + params += std::string(*key_utf8); + params += "="; + params += std::string(*val_utf8); } - first = false; - params += std::string(*key_utf8); - params += "="; - params += std::string(*val_utf8); - } - ret.Reset( isolate, String::NewFromUtf8( isolate, params.c_str() ) ); + ret.Reset(isolate, String::NewFromUtf8(isolate, params.c_str()).ToLocalChecked()); } #if 0 @@ -913,155 +945,157 @@ static void CheckArgType( Local &obj ) } #endif -Connection::Connection( const FunctionCallbackInfo &args ) +Connection::Connection(const FunctionCallbackInfo &args) /***************************************************************/ { - Isolate *isolate = args.GetIsolate(); - HandleScope scope( isolate ); - uv_mutex_init(&conn_mutex); - conn = NULL; - - if( args.Length() > 1 ) { - throwError( JS_ERR_INVALID_ARGUMENTS ); - return; - } + Isolate *isolate = args.GetIsolate(); + Local context = isolate->GetCurrentContext(); + HandleScope scope(isolate); + uv_mutex_init(&conn_mutex); + conn = NULL; - if( args.Length() == 1 ) { - //CheckArgType( args[0] ); - if( args[0]->IsString() ) { - Local str = args[0]->ToString(isolate); -#if NODE_MAJOR_VERSION >= 12 - int string_len = str->Utf8Length(isolate); - char *buf = new char[string_len + 1]; - str->WriteUtf8(isolate, buf); -#else - int string_len = str->Utf8Length(); - char *buf = new char[string_len+1]; - str->WriteUtf8( buf ); -#endif - _arg.Reset( isolate, String::NewFromUtf8( isolate, buf ) ); - delete [] buf; - } else if( args[0]->IsObject() ) { - HashToString( isolate, args[0]->ToObject(isolate), _arg ); - } else if( !args[0]->IsUndefined() && !args[0]->IsNull() ) { - throwError( JS_ERR_INVALID_ARGUMENTS ); - } else { - _arg.Reset( isolate, String::NewFromUtf8( isolate, "" ) ); + if (args.Length() > 1) + { + throwError(JS_ERR_INVALID_ARGUMENTS); + return; } - } else { - _arg.Reset( isolate, String::NewFromUtf8( isolate, "" ) ); - } -} + if (args.Length() == 1) + { + //CheckArgType( args[0] ); + if (args[0]->IsString()) + { + MaybeLocal str = args[0]->ToString(context); + int string_len = str.ToLocalChecked()->Utf8Length(isolate); + char *buf = new char[string_len + 1]; + str.ToLocalChecked()->WriteUtf8(isolate, buf); + _arg.Reset(isolate, String::NewFromUtf8(isolate, buf).ToLocalChecked()); + delete[] buf; + } + else if (args[0]->IsObject()) + { + HashToString(isolate, args[0]->ToObject(context).ToLocalChecked(), _arg); + } + else if (!args[0]->IsUndefined() && !args[0]->IsNull()) + { + throwError(JS_ERR_INVALID_ARGUMENTS); + } + else + { + _arg.Reset(isolate, String::NewFromUtf8(isolate, "").ToLocalChecked()); + } + } + else + { + _arg.Reset(isolate, String::NewFromUtf8(isolate, "").ToLocalChecked()); + } +} Connection::~Connection() /***********************/ { - scoped_lock api_lock( api_mutex ); - scoped_lock lock( conn_mutex ); - - _arg.Reset(); - cleanupStmts(); - if( conn != NULL ) { - api.sqlany_disconnect( conn ); - api.sqlany_free_connection( conn ); - conn = NULL; - openConnections--; - } - - cleanAPI(); + scoped_lock api_lock(api_mutex); + scoped_lock lock(conn_mutex); + + _arg.Reset(); + cleanupStmts(); + if (conn != NULL) + { + api.sqlany_disconnect(conn); + api.sqlany_free_connection(conn); + conn = NULL; + openConnections--; + } + + cleanAPI(); }; -void Connection::cleanupStmts( void ) +void Connection::cleanupStmts(void) /***********************************/ { - std::vector::iterator findit; - for( findit = statements.begin(); findit != statements.end(); findit++ ) { - StmtObject *s = reinterpret_cast(*findit); - s->cleanup(); - } + std::vector::iterator findit; + for (findit = statements.begin(); findit != statements.end(); findit++) + { + StmtObject *s = reinterpret_cast(*findit); + s->cleanup(); + } } -void Connection::removeStmt( class StmtObject *stmt ) +void Connection::removeStmt(class StmtObject *stmt) /***************************************************/ { - // caller must get mutex - std::vector::iterator findit; - for( findit = statements.begin(); findit != statements.end(); findit++ ) { - if( *findit == reinterpret_cast(stmt) ) { - statements.erase( findit ); - return; + // caller must get mutex + std::vector::iterator findit; + for (findit = statements.begin(); findit != statements.end(); findit++) + { + if (*findit == reinterpret_cast(stmt)) + { + statements.erase(findit); + return; + } } - } } Persistent Connection::constructor; -void Connection::Init( Isolate *isolate ) +void Connection::Init(Isolate *isolate) /***************************************/ { - HandleScope scope( isolate ); - // Prepare constructor template - Local tpl = FunctionTemplate::New( isolate, New ); - tpl->SetClassName( String::NewFromUtf8( isolate, "Connection" ) ); - tpl->InstanceTemplate()->SetInternalFieldCount( 1 ); - - // Prototype - NODE_SET_PROTOTYPE_METHOD( tpl, "exec", exec ); - NODE_SET_PROTOTYPE_METHOD( tpl, "prepare", prepare ); - NODE_SET_PROTOTYPE_METHOD( tpl, "connect", connect ); - NODE_SET_PROTOTYPE_METHOD( tpl, "disconnect", disconnect ); - NODE_SET_PROTOTYPE_METHOD( tpl, "close", disconnect ); - NODE_SET_PROTOTYPE_METHOD( tpl, "commit", commit ); - NODE_SET_PROTOTYPE_METHOD( tpl, "rollback", rollback ); - NODE_SET_PROTOTYPE_METHOD( tpl, "connected", connected ); - - Local context = isolate->GetCurrentContext(); - constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); + HandleScope scope(isolate); + // Prepare constructor template + Local tpl = FunctionTemplate::New(isolate, New); + tpl->SetClassName(String::NewFromUtf8(isolate, "Connection").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + NODE_SET_PROTOTYPE_METHOD(tpl, "exec", exec); + NODE_SET_PROTOTYPE_METHOD(tpl, "prepare", prepare); + NODE_SET_PROTOTYPE_METHOD(tpl, "connect", connect); + NODE_SET_PROTOTYPE_METHOD(tpl, "disconnect", disconnect); + NODE_SET_PROTOTYPE_METHOD(tpl, "close", disconnect); + NODE_SET_PROTOTYPE_METHOD(tpl, "commit", commit); + NODE_SET_PROTOTYPE_METHOD(tpl, "rollback", rollback); + NODE_SET_PROTOTYPE_METHOD(tpl, "connected", connected); + + Local context = isolate->GetCurrentContext(); + constructor.Reset(isolate, tpl->GetFunction(context).ToLocalChecked()); } -void Connection::New( const FunctionCallbackInfo &args ) +void Connection::New(const FunctionCallbackInfo &args) /*************************************************************/ { - Isolate *isolate = args.GetIsolate(); - HandleScope scope( isolate ); - - if( args.IsConstructCall() ) { - Connection *obj = new Connection( args ); - obj->Wrap( args.This() ); - args.GetReturnValue().Set( args.This() ); - } else { - const int argc = 1; - Local argv[argc] = { args[0] }; - Local cons = Local::New( isolate, constructor ); -#if NODE_MAJOR_VERSION >= 10 - Local env = isolate->GetCurrentContext(); - MaybeLocal mlObj = cons->NewInstance( env, argc, argv ); - const Local obj = mlObj.ToLocalChecked(); - args.GetReturnValue().Set( obj ); -#else - args.GetReturnValue().Set( cons->NewInstance( argc, argv ) ); -#endif - } + Isolate *isolate = args.GetIsolate(); + HandleScope scope(isolate); + + if (args.IsConstructCall()) + { + Connection *obj = new Connection(args); + obj->Wrap(args.This()); + args.GetReturnValue().Set(args.This()); + } + else + { + const int argc = 1; + Local argv[argc] = {args[0]}; + Local cons = Local::New(isolate, constructor); + Local env = isolate->GetCurrentContext(); + MaybeLocal mlObj = cons->NewInstance(env, argc, argv); + const Local obj = mlObj.ToLocalChecked(); + args.GetReturnValue().Set(obj); + } } -void Connection::NewInstance( const FunctionCallbackInfo &args ) +void Connection::NewInstance(const FunctionCallbackInfo &args) /*********************************************************************/ { - Isolate *isolate = args.GetIsolate(); - HandleScope scope( isolate ); - const unsigned argc = 1; - Local argv[argc] = { args[0] }; - - Local cons = Local::New( isolate, constructor ); -#if NODE_MAJOR_VERSION >= 10 - Local env = isolate->GetCurrentContext(); - MaybeLocal mlObj = cons->NewInstance( env, argc, argv ); - Local instance = mlObj.ToLocalChecked(); -#else - Local instance = cons->NewInstance( argc, argv ); -#endif - args.GetReturnValue().Set( instance ); + Isolate *isolate = args.GetIsolate(); + HandleScope scope(isolate); + const unsigned argc = 1; + Local argv[argc] = {args[0]}; + + Local cons = Local::New(isolate, constructor); + Local env = isolate->GetCurrentContext(); + MaybeLocal mlObj = cons->NewInstance(env, argc, argv); + Local instance = mlObj.ToLocalChecked(); + args.GetReturnValue().Set(instance); } - -#endif // !v010