Skip to content

Commit 1a424ad

Browse files
committed
Add wide statement & multi-row fetch support
New features: 1. A new function on the connection object called connected() which returns true if the connection is connected to a server and false otherwise. 2. Passing an array of arrays rather than an array of values into stmt.exec or conn.exec will execute a wide insert / update / delete. 3. You can prepare multiple select statements at once and then once the first result set is fetched, use stmt.getMoreResults() to get the next result set. Change-Id: Ie928c72c3983d7ad6a8bf0d3fd50d361c579b34e
1 parent 2b58b6d commit 1a424ad

File tree

13 files changed

+1325
-400
lines changed

13 files changed

+1325
-400
lines changed

README.md

Lines changed: 68 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
#node-sqlanywhere
1+
# node-sqlanywhere
22
This is a Node.js driver written for [SAP SQL Anywhere](http://www.sap.com/pc/tech/database/software/sybase-sql-anywhere/index.html).
33

44
[![NPM](https://nodei.co/npm/sqlanywhere.png?compact=true)](https://nodei.co/npm/sqlanywhere/)
55

6-
##Install
6+
## Install
77
```
88
npm install sqlanywhere
99
```
10-
####Prerequisites
10+
#### Prerequisites
1111
This driver communicates with the native SQL Anywhere libraries, and thus requires
12-
native compilation. Native compilation is managed by
13-
[`node-gyp`](https://github.com/TooTallNate/node-gyp/). Please see that project
14-
for additional prerequisites including Python 2.7, and C/C++ tool chain.
12+
native compilation. Native compilation is managed by [`node-gyp`](https://github.com/TooTallNate/node-gyp/). Please see that project for additional prerequisites including Python 2.7, and C/C++ tool chain.
1513

16-
The official version hosted on NPM includes precompiled libraries for Windows
17-
(64-bit).
14+
The official version hosted on NPM includes precompiled libraries for Windows (64-bit).
1815

1916
As of version 1.0.6, the node-sqlanywhere driver supports node.js v0.10, 0.12, 4.x, and 5.x. As of version 1.0.9, it also supports node.js v6.x and v7.x.
2017

21-
##Getting Started
18+
## Getting Started
2219

2320
```js
2421
var sqlanywhere = require('sqlanywhere');
@@ -44,14 +41,11 @@ conn.connect(conn_params, function(err) {
4441
});
4542
```
4643

47-
##Establish a database connection
48-
###Connecting
49-
A database connection object is created by calling `createConnection`. The
50-
connection is established by calling the connection object's `connect` method,
51-
and passing in an object representing connection parameters. The object can
52-
contain most valid [connection properties](http://dcx.sybase.com/index.html#sa160/en/dbadmin/da-conparm.html).
44+
## Establish a database connection
45+
### Connecting
46+
A database connection object is created by calling `createConnection`. The connection is established by calling the connection object's `connect` method, and passing in an object representing connection parameters. The object can contain most valid [connection properties](http://dcx.sybase.com/index.html#sa160/en/dbadmin/da-conparm.html).
5347

54-
#####Example: Connecting over TCP/IP
48+
##### Example: Connecting over TCP/IP
5549
```js
5650
conn.connect({
5751
Host : 'localhost:2638'
@@ -60,7 +54,7 @@ conn.connect({
6054
});
6155
```
6256

63-
#####Example: Auto-starting a database on first connection
57+
##### Example: Auto-starting a database on first connection
6458
```js
6559
conn.connect({
6660
DatabaseFile: 'demo.db',
@@ -70,21 +64,32 @@ conn.connect({
7064
});
7165
```
7266

73-
###Disconnecting
67+
### Disconnecting
68+
69+
The `disconnect()` function closes the connection. As of version 1.0.16, you can also use `close()`.
7470

7571
```js
7672
conn.disconnect(function(err) {
7773
if (err) throw err;
7874
console.log('Disconnected');
7975
});
8076
```
81-
##Direct Statement Execution
82-
Direct statement execution is the simplest way to execute SQL statements. The
83-
inputs are the SQL command to be executed, and an optional array of positional
84-
arguments. The result is returned using callbacks. The type of returned result
85-
depends on the kind of statement.
8677

87-
####DDL Statement
78+
### Determining whether you are connected
79+
The connected() method was added in version 1.0.16.
80+
```js
81+
var conn = sqlanywhere.createConnection();
82+
var connected = conn.connected(); // connected === false
83+
conn.connect({ ... } );
84+
connected = conn.connected(); // connected === true
85+
conn.disconnect();
86+
connected = conn.connected(); // connected === false
87+
```
88+
89+
## Direct Statement Execution
90+
Direct statement execution is the simplest way to execute SQL statements. The inputs are the SQL command to be executed, and an optional array of positional arguments. The result is returned using callbacks. The type of returned result depends on the kind of statement.
91+
92+
#### DDL Statement
8893

8994
In the case of a successful DDL Statement nothing is returned.
9095

@@ -95,7 +100,7 @@ conn.exec('CREATE TABLE Test (id INTEGER PRIMARY KEY DEFAULT AUTOINCREMENT, msg
95100
});
96101
```
97102

98-
####DML Statement
103+
#### DML Statement
99104

100105
In the case of a DML Statement the number of `affectedRows` is returned.
101106

@@ -107,10 +112,9 @@ conn.exec("INSERT INTO Test(msg) SELECT 'Hello,' || row_num FROM sa_rowgenerator
107112
});
108113
```
109114

110-
####Query
115+
#### Query
111116

112-
The `exec` function is a convenient way to completely retrieve the result of a
113-
query. In this case all selected rows are fetched and returned in the callback.
117+
The `exec` function is a convenient way to completely retrieve the result of a query. In this case all selected rows are fetched and returned in the callback.
114118

115119
```js
116120
conn.exec("SELECT * FROM Test WHERE id < 5", function (err, rows) {
@@ -119,8 +123,7 @@ conn.exec("SELECT * FROM Test WHERE id < 5", function (err, rows) {
119123
});
120124
```
121125

122-
Values in the query can be substitued with JavaScript variables by using `?`
123-
placeholders in the query, and passing an array of positional arguments.
126+
Values in the query can be substitued with JavaScript variables by using `?` placeholders in the query, and passing an array of positional arguments.
124127

125128
```js
126129
conn.exec("SELECT * FROM Test WHERE id BETWEEN ? AND ?", [5, 8], function (err, rows) {
@@ -129,8 +132,19 @@ conn.exec("SELECT * FROM Test WHERE id BETWEEN ? AND ?", [5, 8], function (err,
129132
});
130133
```
131134

132-
##Prepared Statement Execution
133-
####Prepare a Statement
135+
As of version 1.0.16, wide inserts, deletes, and updates are possible by passing in an array of arrays, one per row. For example, the following statement inserts three rows rather than just one:
136+
137+
```js
138+
conn.exec("INSERT INTO Test VALUES ( ?, ? )", [ [1, 10], [2, 20], [3, 30] ], function (err, rows) {
139+
if (err) throw err;
140+
console.log('Rows:', rows); // should display 3
141+
});
142+
```
143+
144+
When using wide statements, each array must have the same number of elements and the type of the values must be the same in each row.
145+
146+
## Prepared Statement Execution
147+
#### Prepare a Statement
134148
The connection returns a `statement` object which can be executed multiple times.
135149
```js
136150
conn.prepare('SELECT * FROM Test WHERE id = ?', function (err, stmt){
@@ -139,28 +153,40 @@ conn.prepare('SELECT * FROM Test WHERE id = ?', function (err, stmt){
139153
});
140154
```
141155

142-
####Execute a Statement
143-
The execution of a prepared statement is similar to the direct statement execution.
144-
The first parameter of `exec` function is an array with positional parameters.
156+
#### Execute a Statement
157+
The execution of a prepared statement is similar to the direct statement execution. The first parameter of `exec` function is an array with positional parameters. With version 1.0.16, wide statements (except SELECT) are supported here as well.
158+
145159
```js
146160
stmt.exec([16], function(err, rows) {
147161
if (err) throw err;
148162
console.log("Rows: ", rows);
149163
});
150164
```
151165

152-
####Drop Statement
166+
#### Fetching multiple result sets
167+
As of version 1.0.16, you can prepare and execute a batch containing multiple select statements. To do this, you would prepare the multiple select statements and use `stmt.exec()` to fetch the first result set. To fetch the next result set, call `stmt.getMoreResults()`. getMoreResults takes an optional callback function (which takes the same arguments as `exec`), making it asynchronous. The `getMoreResults()` function returns `undefined` (or passes it to the callback function) after the last result set.
168+
169+
A simple synchronous example is below.
170+
```js
171+
stmt = conn.prepare( 'select 1 as a from dummy; select 2 as b, 3 as c from dummy' );
172+
rs = stmt.exec();
173+
// rs == [ { a: 1 } ]
174+
rs = stmt.getMoreResults();
175+
// rs = [ { b: 2, c: 3 } ]
176+
stmt.drop();
177+
```
178+
179+
#### Drop Statement
153180
```js
154181
stmt.drop(function(err) {
155182
if (err) throw err;
156183
});
157184
```
158185

159-
##Transaction Handling
160-
__Transactions are not automatically commited.__ Executing a statement implicitly
161-
starts a new transaction that must be explicitly committed, or rolled back.
186+
## Transaction Handling
187+
__Transactions are not automatically commited.__ Executing a statement implicitly starts a new transaction that must be explicitly committed, or rolled back.
162188

163-
####Commit a Transaction
189+
#### Commit a Transaction
164190

165191
```js
166192
conn.commit(function(err) {
@@ -169,14 +195,14 @@ conn.commit(function(err) {
169195
});
170196
```
171197

172-
####Rollback a Transaction
198+
#### Rollback a Transaction
173199
```js
174200
conn.rollback(function(err) {
175201
if (err) throw err;
176202
console.log('Transaction rolled back.');
177203
});
178204
```
179205

180-
##Resources
206+
## Resources
181207
+ [SAP SQL Anywhere Documentation](http://dcx.sap.com/)
182208
+ [SAP SQL Anywhere Developer Q&A Forum](http://sqlanywhere-forum.sap.com/)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"author": "SQL ANYWHERE ",
33
"name": "sqlanywhere",
44
"description": "SQL Anywhere JavaScript Driver.",
5-
"version": "1.0.15",
5+
"version": "1.0.16",
66
"repository": {
77
"url": "https://github.com/sqlanywhere/node-sqlanywhere"
88
},

src/h/connection.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,31 @@ class Connection : public ObjectWrap
469469

470470
/// @internal
471471
static void rollbackWork( uv_work_t *req );
472-
472+
473+
/** Indicates whether the connection is connected.
474+
*
475+
* This synchronous method returns true if the connection is connected and
476+
* false otherwise.
477+
*
478+
* The following example shows how to use this method.
479+
*
480+
* <p><pre>
481+
* var sqlanywhere = require( 'sqlanywhere' );
482+
* var client = sqlanywhere.createConnection();
483+
* var connected = client.connected(); // false
484+
* client.connect( "ServerName=demo17;UID=DBA;PWD=sql" )
485+
* connected = client.connected(); // true
486+
* client.disconnect();
487+
* connected = client.connected(); // false
488+
* </pre></p>
489+
*
490+
* @fn Connection::connected()
491+
*
492+
* @return true if the connection is connected, false if not.
493+
*
494+
*/
495+
static NODE_API_FUNC( connected );
496+
473497
public:
474498
/// @internal
475499
a_sqlany_connection *conn;

src/h/errors.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
#define JS_ERR_NOT_CONNECTED -2005
99
#define JS_ERR_BINDING_PARAMETERS -2006
1010
#define JS_ERR_GENERAL_ERROR -2007
11-
#define JS_ERR_RESULTSET -2008
11+
#define JS_ERR_RESULTSET -2008
12+
#define JS_ERR_NO_WIDE_STATEMENTS -2009

0 commit comments

Comments
 (0)