Skip to content

Commit 70e8bc9

Browse files
committed
Added new APIs for Simple Oracle Document Access (SODA)
1 parent 8f810bd commit 70e8bc9

32 files changed

+6752
-396
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## node-oracledb v3.0.0-dev (DD Mon YYYY)
44

5+
- Added new APIs for Simple Oracle Document Access ([SODA](https://github.com/oracle/node-oracledb/blob/master/doc/api.md#sodaoverview)), available when using Oracle Database 18.1 and Oracle client libraries version 18.3, or later.
6+
57
- Added a `drainTime` argument to
68
[`pool.close()`](https://github.com/oracle/node-oracledb/blob/master/doc/api.md#poolclose),
79
allowing pools to be force-closed after a specified number of

binding.gyp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
"src/njsSubscription.cpp",
1212
"src/njsMessages.cpp",
1313
"src/njsIntLob.cpp",
14+
"src/njsSodaDatabase.cpp",
15+
"src/njsSodaCollection.cpp",
16+
"src/njsSodaDocument.cpp",
17+
"src/njsSodaOperation.cpp",
18+
"src/njsSodaDocCursor.cpp",
19+
"src/njsUtils.cpp",
1420
"odpi/src/dpiConn.c",
1521
"odpi/src/dpiContext.c",
1622
"odpi/src/dpiData.c",

doc/api.md

Lines changed: 2616 additions & 341 deletions
Large diffs are not rendered by default.

examples/soda1.js

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. */
2+
3+
/******************************************************************************
4+
*
5+
* You may not use the identified files except in compliance with the Apache
6+
* License, Version 2.0 (the "License.")
7+
*
8+
* You may obtain a copy of the License at
9+
* http://www.apache.org/licenses/LICENSE-2.0.
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
*
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
* NAME
19+
* soda1.js
20+
*
21+
* DESCRIPTION
22+
* Basic Simple Oracle Document Access (SODA) example.
23+
*
24+
* Creates and uses a SODA collection.
25+
* Requires Oracle client 18.3 and Oracle Database 18.1, or higher.
26+
* The user must have been granted the SODA_APP privilege.
27+
* See https://oracle.github.io/node-oracledb/doc/api.html#sodaoverview
28+
*
29+
* This uses Node 8's async/await syntax but could be rewritten to
30+
* use callbacks.
31+
*
32+
*****************************************************************************/
33+
34+
var oracledb = require('oracledb');
35+
var dbConfig = require('./dbconfig.js');
36+
37+
// The general recommendation for simple SODA usage is to enable autocommit
38+
oracledb.autoCommit = true;
39+
40+
async function run() {
41+
let conn, collection;
42+
43+
try {
44+
let soda, indexSpec, content, doc, key, documents, res;
45+
46+
conn = await oracledb.getConnection(dbConfig);
47+
48+
// Create the parent object for SODA
49+
soda = conn.getSodaDatabase();
50+
51+
// Create a new SODA collection and index
52+
// This will open an existing collection, if the name is already in use.
53+
collection = await soda.createCollection("mycollection");
54+
indexSpec = { "name": "CITY_IDX",
55+
"fields": [ {
56+
"path": "address.city",
57+
"datatype": "string",
58+
"order": "asc" } ] };
59+
await collection.createIndex(indexSpec);
60+
61+
// Insert a document.
62+
// A system generated key is created by default.
63+
content = {name: "Matilda", address: {city: "Melbourne"}};
64+
doc = await collection.insertOneAndGet(content);
65+
key = doc.key;
66+
console.log("The key of the new SODA document is: ", key);
67+
68+
// Fetch the document back
69+
doc = await collection.find().key(key).getOne(); // A SodaDocument
70+
content = doc.getContent(); // A JavaScript object
71+
console.log('Retrieved SODA document as an object:');
72+
console.log(content);
73+
content = doc.getContentAsString(); // A JSON string
74+
console.log('Retrieved SODA document as a string:');
75+
console.log(content);
76+
77+
// Replace document contents
78+
content = {name: "Matilda", address: {city: "Sydney"}};
79+
await collection.find().key(key).replaceOne(content);
80+
81+
// Insert some more documents without caring about their keys
82+
content = {name: "Venkat", address: {city: "Bengaluru"}};
83+
await collection.insertOne(content);
84+
content = {name: "May", address: {city: "London"}};
85+
await collection.insertOne(content);
86+
content = {name: "Sally-Ann", address: {city: "San Francisco"}};
87+
await collection.insertOne(content);
88+
89+
// Find all documents with city names starting with 'S'
90+
console.log('Cities starting with S');
91+
documents = await collection.find()
92+
.filter({"address.city": {"$like": "S%"}})
93+
.getDocuments();
94+
95+
for (let i = 0; i < documents.length; i++) {
96+
content = documents[i].getContent();
97+
console.log(' city is: ', content.address.city);
98+
}
99+
100+
// Count all documents
101+
res = await collection.find().count();
102+
console.log('Collection has ' + res.count + ' documents');
103+
104+
// Remove documents with cities containing 'o'
105+
console.log('Removing documents');
106+
res = await collection.find().filter({"address.city": {"$regex": ".*o.*"}}).remove();
107+
console.log('Dropped ' + res.count + ' documents');
108+
109+
// Count all documents
110+
res = await collection.find().count();
111+
console.log('Collection has ' + res.count + ' documents');
112+
113+
} catch (err) {
114+
console.error(err);
115+
} finally {
116+
if (collection) {
117+
// Drop the collection
118+
let res = await collection.drop();
119+
if (res.dropped) {
120+
console.log('Collection was dropped');
121+
}
122+
}
123+
if (conn) {
124+
try {
125+
await conn.close();
126+
} catch (err) {
127+
console.error(err);
128+
}
129+
}
130+
}
131+
}
132+
133+
run();

lib/connection.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
var resultset = require('./resultset.js');
2323
var QueryStream = require('./querystream.js');
2424
var nodbUtil = require('./util.js');
25+
var sodaDatabase = require ('./sodaDatabase.js' ) ;
26+
2527
var executePromisified;
2628
var executeManyPromisified;
2729
var getStatementInfoPromisified;
@@ -356,6 +358,16 @@ function unsubscribe(name, cb) {
356358
unsubscribePromisified = nodbUtil.promisify(unsubscribe);
357359

358360

361+
// To obtain a SodaDatabase object (high-level SODA object associated with
362+
// current connection)
363+
function getSodaDatabase() {
364+
nodbUtil.assert(arguments.length === 0, 'NJS-009');
365+
let db = this._getSodaDatabase();
366+
sodaDatabase.extend(db, this);
367+
return db;
368+
}
369+
370+
359371
// The extend method is used to extend the Connection instance from the C layer with
360372
// custom properties and method overrides. References to the original methods are
361373
// maintained so they can be invoked by the overriding method at the right time.
@@ -478,6 +490,14 @@ function extend(conn, oracledb, pool) {
478490
value: unsubscribePromisified,
479491
enumerable: true,
480492
writable: true
493+
},
494+
_getSodaDatabase: {
495+
value: conn.getSodaDatabase
496+
},
497+
getSodaDatabase: {
498+
value: getSodaDatabase,
499+
enumerable: true,
500+
writable: true
481501
}
482502
}
483503
);

lib/oracledb.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,10 @@ function extend(oracledb) {
616616
value: 4002,
617617
enumerable: true
618618
},
619+
SODA_COLL_MAP_MODE: {
620+
value: 5001,
621+
enumerable : true
622+
},
619623
POOL_STATUS_OPEN: {
620624
value: 6000,
621625
enumerable: true

0 commit comments

Comments
 (0)