├── .gitignore
├── .npmignore
├── README.md
├── binding.gyp
├── build
├── Release
│ ├── addon.exp
│ ├── addon.map
│ └── addon.node
├── addon.vcxproj
├── addon.vcxproj.filters
├── binding.sln
└── config.gypi
├── docker
├── Dockerfile
└── resources
│ └── docker-entrypoint.sh
├── index.js
├── index.test.js
├── package.json
├── src
├── DataHelper.cc
├── DataHelper.h
├── DocumentItem.cc
├── DocumentItem.h
├── addon.cc
├── create_database.cc
├── create_database.h
├── delete_database.cc
├── delete_database.h
├── delete_document_async.cc
├── delete_document_async.h
├── document_async.cc
├── document_async.h
├── getresponse_documents.cc
├── getresponse_documents.h
├── makeresponse_document.cc
├── makeresponse_document.h
├── notes_database.cc
├── notes_database.h
├── notes_document.cc
├── notes_document.h
├── nsf_search.cc
├── nsf_search.h
├── replicate_database_async.cc
├── replicate_database_async.h
├── save_document_async.cc
├── save_document_async.h
├── view_async.cc
└── view_async.h
└── test2.js
/.gitignore:
--------------------------------------------------------------------------------
1 | public/
2 | node_modules/
3 |
4 | build/Debug/
5 | build/Release/obj/
6 | build/
7 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | public/
2 | node_modules/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Node.js driver for NSF
2 |
3 |
4 | *Disclaimer: this is not the official npm module for domino.*
5 |
6 |
7 | ## Install
8 | npm install domino-nsf
9 |
10 | ## Requirements
11 | From release 0.3.0 it's a source release only, to be able to install, you'll need to follow the instructions in the development section.
12 |
13 | Older packages is currently windows only. The binaries has been build for Win32 and tested with Node 8.9.4, 32bit.
14 |
15 | **The Notes program folder needs to be added to the system PATH.**
16 |
17 | ## Linux
18 |
19 | If you want to run on Linux, you'll need to build it from source. Check out development section for more..
20 |
21 |
22 |
23 |
24 |
25 |
26 | ## Usage
27 |
28 | ### Async API
29 |
30 | ```js
31 | const domino = require('domino-nsf')();
32 |
33 | let doc = {
34 | "FullName":"John Smith",
35 | "tags":["test","test2"],
36 | "age":33,
37 | "Form":"Person"
38 | };
39 |
40 | const db = domino.use('database.nsf');
41 |
42 | db.get("documentUNID",function(error,document) {
43 | console.log("document",document);
44 | });
45 |
46 | db.insert(doc,function(error,document) {
47 | // returns the saved document
48 | console.log("document",document);
49 | });
50 |
51 | db.makeResponse(doc,parentDoc,function(err,res) {
52 |
53 | });
54 |
55 | db.view({view:"People",category:""},function(err,view) {
56 | console.log("view result",view);
57 | });
58 |
59 | db.search("SELECT *", functoin(err,results) {
60 | //returns the search results
61 | });
62 |
63 | db.del("documentUNID",function(error,result) {
64 | console.log("result",result);
65 | });
66 |
67 |
68 | // to end session call
69 | domino.termSession();
70 | ```
71 | ### View parameters
72 | ```js
73 | {
74 | view: "the view name",
75 | max: "number, max entries to get"
76 | category: "the category to get"
77 | findByKey: "the key to search by"
78 | exact: true/false, exact or partial match when using findByKey
79 | }
80 | ```
81 |
82 | ### Synchronous API
83 | ```js
84 | const domino = require('domino-nsf')();
85 |
86 | // you must run sinitThread before calling any notes api.
87 | domino.sinitThread();
88 | let db = domino.openDatabase('test.nsf');
89 | let note = db.openNotesNote();
90 | note.setItemText('Form','Test');
91 | note.setItemText('Subject','Hello World!');
92 |
93 | // save the note
94 | note.updateNote();
95 |
96 | // close the note and db
97 | note.close();
98 | db.close();
99 |
100 |
101 | // terminate thread before exiting
102 | domino.stermThread();
103 |
104 | ```
105 |
106 | ### Avaliable methods
107 | #### Domino object
108 |
109 | sinitThread()
110 | init the notes session/thread
111 |
112 | stermThread()
113 | terminate the notes thread
114 |
115 | createDatabase('server!!path/databasename.nsf')
116 | create a new **database**, on given serve and path. If path is omitted, localhost is used.
117 | Returns a **database** object.
118 |
119 | openDatabase('server!!path/databasename.nsf')
120 | Opens a database.
121 | Returns a **database** object.
122 |
123 | deleteDatabase('server!!path/databasename.nsf');
124 |
125 | #### Database object
126 | openNotesNote('unid')
127 | Opens a Notes note by *UNID*.
128 | Returns a **note** object.
129 |
130 | createNotesNote()
131 | Creates a new note in the database.
132 | Returns a Notes object.
133 |
134 | getDatabaseName()
135 | Return the database name / title.
136 |
137 | close()
138 | Closes the database handle.
139 |
140 | #### Notes object
141 | getItemText('itemName')
142 | returns the items value as a string, returns empty string if item does not exists.
143 |
144 | getItemNumber('itemName')
145 | returns the items value as a number
146 |
147 | getItemDate('itemName')
148 |
149 | return item date value as js date.
150 |
151 | getItemValue('itemName')
152 | returns the item value as a text,number,text array or date depending on type.
153 |
154 | getItemMime('itemName')
155 | returns the mime item.
156 |
157 | hasItem('itemName')
158 | returns true/false if note has item.
159 |
160 | getUNID()
161 | returns the note UNID
162 |
163 | updateNote()
164 | saves the note to database.
165 |
166 | setItemText('itemName','string')
167 | set a string value to an item. If the item exists, it will replace the item value.
168 |
169 | setItemDate('itemName', date)
170 | set a Date object value to an item
171 |
172 | setItemNumber('itemName,number)
173 | set a number value to an item. If the item exists, it will replace the item value.
174 |
175 | setItemValue('itemName', value);
176 | set an value to an item, value can be text,number,text array or js Date object
177 |
178 | setItemMime('itemName','header',value);
179 | set an mime item.
180 |
181 | appendItemValue('itemName','string')
182 | append a string value to an existing text array.
183 |
184 | deleteItem('itemName')
185 | delete an item from a note.
186 | Returns true if item was deleted.
187 |
188 | close()
189 | Close the note handle. After calling close, you cannot call any methods on the current **Note** object.
190 |
191 | ## Development and Contribution
192 |
193 | ### Local Development Windows
194 | To build the addon, you need the
195 | * Domino C API
196 | * Nan for Node.js.
197 | * Microsoft VisualStudio 2015/2017 or by using using Microsoft's windows-build-tools
198 | * [node-gyp](https://github.com/nodejs/node-gyp)
199 |
200 |
201 | #### Configuring enviroment for node-gyp build
202 | You must set these environment variables before you build the addon
203 |
204 | NOTES_INCLUDE must contain:
205 | * the C API header files
206 |
207 | NOTES_LIB must contain:
208 | * the path to the Notes C library folder
209 |
210 | ### Linux/Docker
211 | To set up a development enviroment using Docker, you can use this [Dockerfile](https://github.com/nthjelme/nodejs-domino/blob/master/docker/Dockerfile)
212 |
213 |
214 | #### Configuring and building
215 | node-gyp configure
216 | ..and build..
217 |
218 | node-gyp build
219 |
220 |
221 |
--------------------------------------------------------------------------------
/binding.gyp:
--------------------------------------------------------------------------------
1 | {
2 | "targets": [
3 | {
4 | "target_name": "addon",
5 | "sources": [
6 | "src/addon.cc",
7 | "src/document_async.cc",
8 | "src/save_document_async.cc",
9 | "src/makeresponse_document.cc",
10 | "src/delete_document_async.cc",
11 | "src/view_async.cc",
12 | "src/DocumentItem.cc",
13 | "src/DataHelper.cc",
14 | "src/create_database.cc",
15 | "src/delete_database.cc",
16 | "src/nsf_search.cc",
17 | "src/notes_document.cc",
18 | "src/notes_database.cc",
19 | ],
20 | "conditions": [
21 | ["OS==\"linux\"",{
22 | "include_dirs": ["
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {53EFA712-345C-0CF5-4A70-18A62C9221EE}
15 | Win32Proj
16 | addon
17 | true
18 | x64
19 |
20 |
21 |
22 | DynamicLibrary
23 |
24 |
25 | v140
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | $(ExecutablePath);$(MSBuildProjectDirectory)\..\bin\;$(MSBuildProjectDirectory)\..\bin\
36 | true
37 | $(Configuration)\obj\$(ProjectName)\
38 | false
39 | true
40 | $(SolutionDir)$(Configuration)\
41 | .node
42 | .node
43 | .node
44 | .node
45 | $(ProjectName)
46 | $(OutDir)\$(ProjectName).node
47 |
48 |
49 |
50 | C:\Users\NilsTarjei\.node-gyp\6.9.1\include\node;C:\Users\NilsTarjei\.node-gyp\6.9.1\src;C:\Users\NilsTarjei\.node-gyp\6.9.1\deps\uv\include;C:\Users\NilsTarjei\.node-gyp\6.9.1\deps\v8\include;..\..\node_modules\nan;C:\notesapi\notesapi901\include;%(AdditionalIncludeDirectories)
51 | EnableFastChecks
52 | true
53 | false
54 | ProgramDatabase
55 | 4351;4355;4800;4251;%(DisableSpecificWarnings)
56 | false
57 | false
58 | false
59 | Disabled
60 | NotUsing
61 | NODE_GYP_MODULE_NAME=addon;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;W32;BUILDING_NODE_EXTENSION;DEBUG;_DEBUG;%(PreprocessorDefinitions)
62 | MultiThreadedDebug
63 | true
64 | true
65 | false
66 | Level3
67 |
68 |
69 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;DelayImp.lib;"C:\Users\NilsTarjei\.node-gyp\6.9.1\$(Configuration)\node.lib";C:\notesapi\notesapi901\lib\\mswin32\notes.lib;C:\notesapi\notesapi901\lib\\mswin32\notescpp.lib
70 | /ignore:4199 %(AdditionalOptions)
71 | true
72 | true
73 | iojs.exe;node.exe;%(DelayLoadDLLs)
74 | true
75 | true
76 | true
77 | $(OutDir)$(ProjectName).node
78 | true
79 | true
80 | .node
81 | MachineX86
82 |
83 |
84 | C:\Users\NilsTarjei\.node-gyp\6.9.1\include\node;C:\Users\NilsTarjei\.node-gyp\6.9.1\src;C:\Users\NilsTarjei\.node-gyp\6.9.1\deps\uv\include;C:\Users\NilsTarjei\.node-gyp\6.9.1\deps\v8\include;..\..\node_modules\nan;C:\notesapi\notesapi901\include;%(AdditionalIncludeDirectories)
85 | NODE_GYP_MODULE_NAME=addon;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;W32;BUILDING_NODE_EXTENSION;DEBUG;_DEBUG;%(PreprocessorDefinitions);%(PreprocessorDefinitions)
86 |
87 |
88 |
89 |
90 | C:\Users\NilsTarjei\.node-gyp\6.9.1\include\node;C:\Users\NilsTarjei\.node-gyp\6.9.1\src;C:\Users\NilsTarjei\.node-gyp\6.9.1\deps\uv\include;C:\Users\NilsTarjei\.node-gyp\6.9.1\deps\v8\include;..\..\node_modules\nan;C:\notesapi\notesapi901\include;%(AdditionalIncludeDirectories)
91 | /MP %(AdditionalOptions)
92 | true
93 | false
94 | ProgramDatabase
95 | 4351;4355;4800;4251;%(DisableSpecificWarnings)
96 | false
97 | Speed
98 | true
99 | AnySuitable
100 | true
101 | true
102 | Full
103 | NotUsing
104 | NODE_GYP_MODULE_NAME=addon;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;W32;BUILDING_NODE_EXTENSION;%(PreprocessorDefinitions)
105 | MultiThreaded
106 | false
107 | true
108 | true
109 | false
110 | Level3
111 | true
112 |
113 |
114 | /LTCG %(AdditionalOptions)
115 |
116 |
117 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;DelayImp.lib;"C:\Users\NilsTarjei\.node-gyp\6.9.1\$(Configuration)\node.lib";C:\notesapi\notesapi901\lib\\mswin32\notes.lib;C:\notesapi\notesapi901\lib\\mswin32\notescpp.lib
118 | /ignore:4199 %(AdditionalOptions)
119 | true
120 | true
121 | iojs.exe;node.exe;%(DelayLoadDLLs)
122 | true
123 | true
124 | true
125 | UseLinkTimeCodeGeneration
126 | true
127 | true
128 | $(OutDir)$(ProjectName).node
129 | true
130 | true
131 | .node
132 | MachineX86
133 |
134 |
135 | C:\Users\NilsTarjei\.node-gyp\6.9.1\include\node;C:\Users\NilsTarjei\.node-gyp\6.9.1\src;C:\Users\NilsTarjei\.node-gyp\6.9.1\deps\uv\include;C:\Users\NilsTarjei\.node-gyp\6.9.1\deps\v8\include;..\..\node_modules\nan;C:\notesapi\notesapi901\include;%(AdditionalIncludeDirectories)
136 | NODE_GYP_MODULE_NAME=addon;USING_UV_SHARED=1;USING_V8_SHARED=1;V8_DEPRECATION_WARNINGS=1;WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;W32;BUILDING_NODE_EXTENSION;%(PreprocessorDefinitions);%(PreprocessorDefinitions)
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
--------------------------------------------------------------------------------
/build/addon.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
6 |
7 |
8 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
9 |
10 |
11 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
12 |
13 |
14 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
15 |
16 |
17 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
18 |
19 |
20 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
21 |
22 |
23 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
24 |
25 |
26 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
27 |
28 |
29 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
30 |
31 |
32 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
33 |
34 |
35 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
36 |
37 |
38 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
39 |
40 |
41 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
42 |
43 |
44 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
45 |
46 |
47 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
48 |
49 |
50 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
51 |
52 |
53 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
54 |
55 |
56 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
57 |
58 |
59 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
60 |
61 |
62 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
63 |
64 |
65 | {7B735499-E5DD-1C2B-6C26-70023832A1CF}
66 |
67 |
68 | {E9F714C1-DA89-54E2-60CF-39FEB20BF756}
69 |
70 |
71 | {92BC873D-B0F7-121B-EC88-F0153AE4D43D}
72 |
73 |
74 | {F852EB63-437C-846A-220F-8D9ED6DAEC1D}
75 |
76 |
77 | {D51E5808-912B-5C70-4BB7-475D1DBFA067}
78 |
79 |
80 | {741E0E76-39B2-B1AB-9FA1-F1A20B16F295}
81 |
82 |
83 | {56DF7A98-063D-FB9D-485C-089023B4C16A}
84 |
85 |
86 | {77348C0E-2034-7791-74D5-63C077DF5A3B}
87 |
88 |
89 | {8CDEE807-BC53-E450-C8B8-4DEBB66742D4}
90 |
91 |
92 | {739DB09A-CC57-A953-A6CF-F64FA08E4FA7}
93 |
94 |
95 |
96 |
97 | ..\src
98 |
99 |
100 | ..\src
101 |
102 |
103 | ..\src
104 |
105 |
106 | ..\src
107 |
108 |
109 | ..\src
110 |
111 |
112 | ..\src
113 |
114 |
115 | ..\src
116 |
117 |
118 | ..\src
119 |
120 |
121 | ..\src
122 |
123 |
124 | ..\src
125 |
126 |
127 | C:\Users\NilsTarjei\AppData\Roaming\npm\node_modules\node-gyp\src
128 |
129 |
130 | ..
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/build/binding.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2015
3 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "addon", "addon.vcxproj", "{53EFA712-345C-0CF5-4A70-18A62C9221EE}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Win32 = Debug|Win32
8 | Release|Win32 = Release|Win32
9 | EndGlobalSection
10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
11 | {53EFA712-345C-0CF5-4A70-18A62C9221EE}.Debug|Win32.ActiveCfg = Debug|Win32
12 | {53EFA712-345C-0CF5-4A70-18A62C9221EE}.Debug|Win32.Build.0 = Debug|Win32
13 | {53EFA712-345C-0CF5-4A70-18A62C9221EE}.Release|Win32.ActiveCfg = Release|Win32
14 | {53EFA712-345C-0CF5-4A70-18A62C9221EE}.Release|Win32.Build.0 = Release|Win32
15 | EndGlobalSection
16 | GlobalSection(SolutionProperties) = preSolution
17 | HideSolutionNode = FALSE
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/build/config.gypi:
--------------------------------------------------------------------------------
1 | # Do not edit. File was generated by node-gyp's "configure" step
2 | {
3 | "target_defaults": {
4 | "cflags": [],
5 | "default_configuration": "Release",
6 | "defines": [],
7 | "include_dirs": [],
8 | "libraries": []
9 | },
10 | "variables": {
11 | "asan": 0,
12 | "debug_devtools": "node",
13 | "force_dynamic_crt": 0,
14 | "host_arch": "x64",
15 | "icu_data_file": "icudt57l.dat",
16 | "icu_data_in": "..\\..\\deps/icu-small\\source/data/in\\icudt57l.dat",
17 | "icu_endianness": "l",
18 | "icu_gyp_path": "tools/icu/icu-generic.gyp",
19 | "icu_locales": "en,root",
20 | "icu_path": "deps/icu-small",
21 | "icu_small": "true",
22 | "icu_ver_major": "57",
23 | "node_byteorder": "little",
24 | "node_enable_d8": "false",
25 | "node_enable_v8_vtunejit": "false",
26 | "node_install_npm": "true",
27 | "node_module_version": 48,
28 | "node_no_browser_globals": "false",
29 | "node_prefix": "/usr/local",
30 | "node_release_urlbase": "https://nodejs.org/download/release/",
31 | "node_shared": "false",
32 | "node_shared_cares": "false",
33 | "node_shared_http_parser": "false",
34 | "node_shared_libuv": "false",
35 | "node_shared_openssl": "false",
36 | "node_shared_zlib": "false",
37 | "node_tag": "",
38 | "node_use_bundled_v8": "true",
39 | "node_use_dtrace": "false",
40 | "node_use_etw": "true",
41 | "node_use_lttng": "false",
42 | "node_use_openssl": "true",
43 | "node_use_perfctr": "true",
44 | "node_use_v8_platform": "true",
45 | "openssl_fips": "",
46 | "openssl_no_asm": 0,
47 | "shlib_suffix": "so.48",
48 | "target_arch": "ia32",
49 | "v8_enable_gdbjit": 0,
50 | "v8_enable_i18n_support": 1,
51 | "v8_inspector": "true",
52 | "v8_no_strict_aliasing": 1,
53 | "v8_optimized_debug": 0,
54 | "v8_random_seed": 0,
55 | "v8_use_snapshot": "true",
56 | "want_separate_host_toolset": 1,
57 | "nodedir": "C:\\Users\\NilsTarjei\\.node-gyp\\6.9.1",
58 | "copy_dev_lib": "true",
59 | "standalone_static_library": 1
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nils/domino:9.0.1-fp8
2 |
3 | EXPOSE 25 80 443 1352
4 |
5 | COPY resources/docker-entrypoint.sh /
6 | RUN chmod 775 /docker-entrypoint.sh
7 | RUN apt-get update && \
8 | apt-get -y install nodejs npm python build-essential && \
9 | rm -rf /var/lib/apt/lists/* && \
10 | wget -q http://172.17.0.1:7777/notesapi.tar.gz && \
11 | tar -xf notesapi.tar.gz -C /opt/ibm/ && \
12 | mkdir /home/notes/samples && \
13 | cp -a /opt/ibm/notesapi/samples/. /home/notes/samples && \
14 | ln -s /opt/ibm/domino/notes/latest/linux/libnotes.so /usr/lib/libnotes.so && \
15 | ln -s /opt/ibm/domino/notes/latest/linux/libndgts.so /usr/lib/libndgts.so && \
16 | ln -s /opt/ibm/domino/notes/latest/linux/libxmlproc.so /usr/lib/libxmlproc.so && \
17 | ln -s /opt/ibm/domino/notes/latest/linux/libgsk8iccs_64.so /usr/lib/libgsk8iccs_64.so && \
18 | npm install -g n && \
19 | n stable && \
20 | npm install -g node-gyp nan
21 |
22 |
23 | USER notes
24 | WORKDIR /local/notesdata
25 | ENV LOGNAME=notes
26 | ENV LOTUS=/opt/ibm
27 | ENV Notes_ExecDirectory=/opt/ibm/domino/notes/latest/linux
28 | ENV NOTES_DATA_DIR=/local/notesdata
29 | ENV DOMINO_RES_DIR=/opt/ibm/domino/notes/latest/res/C
30 |
31 | ENV PATH=$PATH:/opt/ibm/domino/:$Notes_ExecDirectory:$NOTES_DATA_DIR:$DOMINO_RES_DIR
32 |
33 | ENTRYPOINT ["/docker-entrypoint.sh"]
34 |
--------------------------------------------------------------------------------
/docker/resources/docker-entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | serverID=/local/notesdata/server.id
4 |
5 | if [ ! -f "$serverID" ]; then
6 | /opt/ibm/domino/bin/server -listen 1352
7 | else
8 | /opt/ibm/domino/rc_domino_script start
9 | /bin/bash
10 | fi
11 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = Domino;
2 | var dominoDriver = require('./build/Release/addon');
3 |
4 | function Domino() {
5 | dominoDriver.initSession();
6 | var dbObj = {};
7 | var termSession = function() {
8 | dominoDriver.termSession();
9 | };
10 |
11 | var createDatabase = function(db,callback) {
12 | dominoDriver.createDatabase(db,function(error,response) {
13 | callback(error,response);
14 | });
15 | };
16 |
17 | var deleteDatabase = function(db,callback) {
18 | dominoDriver.deleteDatabase(db,function(error,status) {
19 | callback(error,status);
20 | });
21 | };
22 |
23 | var sinitThread = function() {
24 | dominoDriver.sinitThread();
25 | }
26 |
27 | var stermThread = function() {
28 | dominoDriver.stermThread();
29 | }
30 |
31 | var openDatabase = function(databaseName) {
32 |
33 | var db = {handle:0};
34 | db.handle = dominoDriver.openDatabase(databaseName);
35 | if (db.handle==0) {
36 | throw Error("Error opening database");
37 | } else {
38 | db.getDatabaseName = function() {
39 | return dominoDriver.getDatabaseName(db.handle);
40 | }
41 |
42 | db.close = function() {
43 | dominoDriver.closeDatabase(db.handle);
44 | db.handle=0;
45 | }
46 |
47 | var baseNote = {};
48 | baseNote.getItemText = function(itemName) {
49 | return dominoDriver.getItemText(this.handle,itemName);
50 | }
51 | baseNote.setItemText = function(itemName,value) {
52 | dominoDriver.setItemText(this.handle, itemName, value);
53 | }
54 | baseNote.getItemNumber = function(itemName) {
55 | return dominoDriver.getItemNumber(this.handle,itemName);
56 | }
57 | baseNote.setItemNumber = function(itemName,value) {
58 | return dominoDriver.setItemNumber(this.handle,itemName,value);
59 | }
60 | baseNote.getItemDate = function(itemName) {
61 | return dominoDriver.getItemDate(this.handle,itemName);
62 | }
63 | baseNote.setItemDate = function(itemName, date) {
64 | return dominoDriver.setItemDate(this.handle,itemName,date);
65 | }
66 |
67 | baseNote.getItemValue = function(itemName) {
68 | return dominoDriver.getItemValue(this.handle,itemName);
69 | }
70 | baseNote.hasItem = function(itemName) {
71 | return dominoDriver.hasItem(this.handle,itemName);
72 | }
73 | baseNote.deleteItem = function(itemName) {
74 | return dominoDriver.deleteItem(this.handle,itemName);
75 | }
76 | baseNote.setAuthor = function(itemName,value) {
77 | return dominoDriver.setAuthor(this.handle,itemName,value);
78 | }
79 | baseNote.setItemValue = function(itemName,value) {
80 | return dominoDriver.setItemValue(this.handle,itemName,value);
81 | }
82 |
83 |
84 | baseNote.setItemMime = function(itemName, header,body) {
85 | if (!header) {
86 | header = 'Content-Type: application/json';
87 | }
88 | return dominoDriver.setMimeItem(this.handle,itemName,body,header);
89 | }
90 |
91 | baseNote.getItemMime = function(itemName) {
92 | let mimeItem = {
93 | value: dominoDriver.getMimeItem(this.handle,itemName)
94 | }
95 | return mimeItem;
96 | }
97 |
98 | baseNote.appendItemValue = function(itemName, itemToAppend) {
99 | return dominoDriver.appendItemTextList(this.handle,itemName,itemToAppend);
100 | }
101 |
102 | baseNote.updateNote = function() {
103 | dominoDriver.updateNote(this.handle);
104 | }
105 | baseNote.close = function() {
106 | dominoDriver.closeNote(this.handle);
107 | }
108 | baseNote.getUNID = function() {
109 | return dominoDriver.getNoteUNID(this.handle);
110 | }
111 |
112 | db.createNotesNote = function() {
113 | var note = Object.create(baseNote);
114 | note.handle = dominoDriver.createNotesNote(db.handle);
115 | return note;
116 | }
117 |
118 | db.openNotesNote = function(unid) {
119 | var note = Object.create(baseNote);
120 | note.handle = dominoDriver.getNotesNote(db.handle,unid);
121 |
122 | return note;
123 | }
124 | }
125 | return db;
126 | }
127 |
128 | var use = function(db) {
129 | var localDb = {database: db};
130 |
131 | var replicate = function(callback) {
132 | callback({error:"Not implemented"},undefined);
133 | /*dominoDriver.replicateAsync(db,function(error,result) {
134 | callback(error,result);
135 | });*/
136 | }
137 |
138 | var get = function(unid,param1,param2) {
139 | if (typeof (param1) == 'function') {
140 | dominoDriver.getDocumentAsync(localDb,unid,function(error,document) {
141 | if (document) {
142 | document.getResponses = function(responseCallback) {
143 | dominoDriver.getResponseDocumentsAsync(localDb,this["@unid"], function(err,res) {
144 | responseCallback(err,res);
145 | });
146 | };
147 | document.makeResponse = function(parent,responseCallback) {
148 | dominoDriver.makeResponseDocumentAsync(localDb,this["@unid"], parent["@unid"], function(error,result) {
149 | responseCallback(error,result);
150 | });
151 | }
152 | document.save = function(documentCallback) {
153 | dominoDriver.saveDocumentAsync(localDb,this,function(error,document) {
154 | documentCallback(error,document);
155 | });
156 |
157 | }
158 | }
159 | param1(error,document);
160 | });
161 | } else if (typeof (param2 == 'function')) {
162 | dominoDriver.getDocumentAsync(localDb,unid,param1,function(error,document) {
163 | if (document) {
164 | document.getResponses = function(responseCallback) {
165 | dominoDriver.getResponseDocumentsAsync(localDb,this["@unid"], function(err,res) {
166 | responseCallback(err,res);
167 | });
168 | };
169 | document.makeResponse = function(parent,responseCallback) {
170 | dominoDriver.makeResponseDocumentAsync(localDb,this["@unid"], parent["@unid"], function(error,result) {
171 | responseCallback(error,result);
172 | });
173 | }
174 | document.save = function(documentCallback) {
175 | dominoDriver.saveDocumentAsync(localDb,this,function(error,document) {
176 | documentCallback(error,document);
177 | });
178 |
179 | }
180 | }
181 | param2(error,document);
182 | });
183 | }
184 |
185 | }
186 |
187 |
188 | var insert = function(document,callback) {
189 | dominoDriver.saveDocumentAsync(localDb,document,function(error,document) {
190 | callback(error,document);
191 | });
192 | };
193 |
194 | var deleteFn = function(unid,callback) {
195 | dominoDriver.deleteDocumentAsync(localDb,unid,function(error,result) {
196 | callback(error,result);
197 | });
198 | };
199 |
200 | var makeResponse = function(doc,parent,callback) {
201 | dominoDriver.makeResponseDocumentAsync(localDb,doc["@unid"], parent["@unid"], function(error,result) {
202 | callback(error,result);
203 | });
204 | };
205 |
206 | var getResponses = function(doc,callback) {
207 | callback({error: "Not implemented"},undefined)
208 | /*
209 | dominoDriver.getResponseDocumentsAsync(localDb,doc["@unid"], function(error,result) {
210 | callback(error,result);
211 | });*/
212 | };
213 |
214 | var view = function(view,callback) {
215 | dominoDriver.getViewAsync(localDb,view,function(err,result) {
216 | callback(err,result);
217 | });
218 | };
219 |
220 | var search = function(searchFormula,callback) {
221 | dominoDriver.searchNsfAsync(localDb,searchFormula,function(err,result) {
222 | callback(err,result);
223 | });
224 | }
225 |
226 | localDb.get = get;
227 | localDb.insert = insert;
228 | localDb.del = deleteFn;
229 | localDb.view = view;
230 | localDb.replicate = replicate;
231 | localDb.makeResponse = makeResponse;
232 | localDb.search = search;
233 |
234 | return localDb;
235 |
236 | };
237 | process.on('SIGINT', function() {
238 | dominoDriver.termSession();
239 | process.exit();
240 | });
241 |
242 | dbObj.use = use;
243 | dbObj.termSession = termSession;
244 | dbObj.createDatabase = createDatabase;
245 | dbObj.deleteDatabase = deleteDatabase;
246 | dbObj.openDatabase = openDatabase;
247 | dbObj.sinitThread = sinitThread;
248 | dbObj.stermThread = stermThread;
249 |
250 | return dbObj;
251 | };
252 |
--------------------------------------------------------------------------------
/index.test.js:
--------------------------------------------------------------------------------
1 | var expect = require('chai').expect;
2 | var dominoNsf = require('./index');
3 | var domino = dominoNsf();
4 |
5 | var db;
6 | var savedDocumentUnid = "";
7 | var doc = {
8 | "Form":"Test",
9 | "Name": "Test",
10 | "date": new Date(0),
11 | "number": 10,
12 | "array": ["a","b","c"]
13 | };
14 | var test_db = {
15 | "database":"nodejs_domino9.nsf",
16 | "title":"Test database"
17 | }
18 |
19 |
20 | describe('domino-nsf',function() {
21 |
22 | before(function() {
23 | domino.createDatabase(test_db,function(error, database) {
24 | if (error) {
25 | console.error(error);
26 | }
27 | db = domino.use(database.database);
28 | });
29 |
30 | });
31 |
32 | after(function() {
33 | domino.deleteDatabase(test_db,function(error,status) {
34 | if (error) {
35 | console.log("error deleting database,",error);
36 | }
37 | });
38 | domino.termSession();
39 | });
40 |
41 | describe('save document',function() {
42 | var savedDocument = {};
43 | before(function(done) {
44 | db.insert(doc,function(err,result) {
45 | if(err) {
46 | done(err);
47 | } else {
48 | savedDocument = result;
49 | savedDocumentUnid = result["@unid"];
50 | done();
51 | }
52 | });
53 | });
54 | it ('should create a document with unid with length of 32', function() {
55 | expect(savedDocument).to.have.property('@unid').with.length(32);
56 | });
57 | it ('should have a number property that equals 10', function() {
58 | expect(savedDocument).to.have.property('number').to.equal(10);
59 | });
60 | it('should have a date property that equals ', function() {
61 | expect(savedDocument).to.have.property('date').to.eql(new Date(0));
62 | });
63 | it('shoud have a Name property that equals "Test"',function() {
64 | expect(savedDocument).to.have.property('Name').to.eql("Test");
65 | });
66 | it('shoud have a array property that equals ["a","b","c"]',function() {
67 | expect(savedDocument).to.have.property('array').to.eql(["a","b","c"]);
68 | });
69 | });
70 | describe('get document fields', function() {
71 | var document = {};
72 | before(function(done) {
73 | db.get(savedDocumentUnid,{fields: ['Name','Number']},function(err,result) {
74 | if (err) {
75 | done(err);
76 | } else {
77 | document = result;
78 | done();
79 | }
80 | });
81 | });
82 | it('shoud have a Name property that equals "Test"',function() {
83 | expect(document).to.have.property('Name').to.eql("Test");
84 | });
85 | it('shoud have not have a date property ',function() {
86 | expect(document).to.not.have.property('date');
87 | });
88 | });
89 | describe('get all document items', function() {
90 | var document = {};
91 |
92 | before(function(done) {
93 | db.get(savedDocumentUnid,function(err,result) {
94 | if (err) {
95 | done(err);
96 | } else {
97 | document = result;
98 | done();
99 | }
100 | });
101 | });
102 |
103 | it ('should create a document with unid with length of 32', function() {
104 | expect(document).to.have.property('@unid').with.length(32);
105 | });
106 | it ('should have a number property that equals 10', function() {
107 | expect(document).to.have.property('number').to.equal(10);
108 | });
109 | it('should have a date property that equals ', function() {
110 | expect(document).to.have.property('date').to.eql(new Date(0));
111 | });
112 | it('shoud have a Name property that equals "Test"',function() {
113 | expect(document).to.have.property('Name').to.eql("Test");
114 | });
115 | it('shoud have a array property that equals ["a","b","c"]',function() {
116 | expect(document).to.have.property('array').to.eql(["a","b","c"]);
117 | });
118 |
119 | });
120 |
121 | describe('search database', function() {
122 | var searchResults = [];
123 | before(function(done) {
124 | db.search("SELECT *",function(err,result) {
125 | if (err) {
126 | done(err);
127 | } else {
128 | searchResults = result;
129 | done();
130 | }
131 | });
132 | });
133 |
134 | it('expect a list of documents with length of 1',function() {
135 | expect(searchResults).to.have.lengthOf(1);
136 | });
137 |
138 | });
139 |
140 | describe('open database and get name', function() {
141 | let db = {};
142 | let note = {};
143 | let newNote = {};
144 | const body = "This is a body";
145 | before(function(done) {
146 | domino.sinitThread();
147 | db = domino.openDatabase(test_db.database);
148 | note = db.openNotesNote(savedDocumentUnid);
149 | const header = "Content-Type: application/text";
150 | note.setItemMime("Body",header,body);
151 | note.updateNote();
152 | done();
153 | });
154 |
155 | it('should have a mime item body', function() {
156 | expect(note.getItemMime("Body").value).to.be.equal(body);
157 | });
158 |
159 | it('should have a name equals ' + test_db.title, function() {
160 | expect(db.getDatabaseName()).to.be.equal(test_db.title);
161 | });
162 |
163 | it('should have a note.Name equals to ' + doc.Name, function() {
164 | expect(note.getItemText("Name")).to.be.equal(doc.Name);
165 | });
166 |
167 | it('should have a note.Number equals to ' + doc.number, function() {
168 | expect(note.getItemNumber("number")).to.be.equal(doc.number);
169 | });
170 |
171 | it ('should return a number value', function() {
172 | expect(note.getItemValue("number")).to.be.equal(doc.number);
173 | });
174 |
175 | it ('should return a text value', function() {
176 | expect(note.getItemValue("Name")).to.be.equal(doc.Name);
177 | })
178 |
179 | it('should have a note.Date equals to ' + doc.date, function() {
180 | expect(new Date(note.getItemDate("date")).getTime()).to.be.equal(doc.date.getTime());
181 | });
182 |
183 | it('should return a date equals to ' + doc.date, function() {
184 | expect(note.getItemValue("date").toString()).to.be.equal(doc.date.toString());
185 | })
186 |
187 | it('should create a new note and get a handle', function() {
188 | newNote = db.createNotesNote();
189 | expect(newNote.handle).to.not.equal(0);
190 | });
191 |
192 | it('should create a item on newly created note', function() {
193 | newNote.setItemText("test", "test value");
194 | expect(newNote.getItemText("test")).to.be.equal("test value");
195 | });
196 |
197 |
198 | it('hasItem should return true', function() {
199 | expect(newNote.hasItem("test")).to.be.true;
200 |
201 | });
202 |
203 | it('deleted item should be empty', function() {
204 | newNote.deleteItem("test");
205 | expect(newNote.getItemText("test")).to.be.equal("");
206 | });
207 |
208 | it('should create a number item on newly created note', function() {
209 | newNote.setItemNumber("tall", 33.3);
210 | expect(newNote.getItemNumber("tall")).to.be.equal(33.3);
211 | });
212 |
213 | it('should create an array item on newly created note', function() {
214 | var text_list = ["Text1","Text2","Text3"];
215 | newNote.setItemValue("text_list",text_list);
216 | expect(newNote.getItemValue("text_list")).to.deep.equal(text_list);
217 | });
218 |
219 | it('should append a value to the array', function() {
220 | let text_list = ["Text1","Text2","Text3"];
221 | let textToAppend = "Text4";
222 | text_list.push(textToAppend);
223 | newNote.appendItemValue("text_list",textToAppend);
224 | expect(newNote.getItemValue("text_list")).to.deep.equal(text_list);
225 |
226 | });
227 |
228 | it('should create a date item', function() {
229 | let date = new Date();
230 | newNote.setItemDate("date_test",date);
231 | // notes does not save ms in dates, compare the date strings instead.
232 | expect(newNote.getItemDate("date_test").toString()).to.be.equal(date.toString());
233 | })
234 |
235 | it('should save the newnote and get the note unid', function() {
236 | newNote.updateNote();
237 | expect(newNote.getUNID()).to.have.lengthOf(32);
238 | });
239 |
240 |
241 |
242 |
243 | after(function(done) {
244 | note.close();
245 | db.close();
246 | domino.stermThread();
247 | done();
248 | })
249 | });
250 |
251 | describe('delete document', function() {
252 | var deleteResult = {};
253 | before(function(done) {
254 | db.del(savedDocumentUnid,function(err,result) {
255 | if (err) {
256 | done(err);
257 | } else {
258 | deleteResult = result;
259 | done();
260 | }
261 | });
262 | });
263 | it('should return status property that equals "deleted"',function() {
264 | expect(deleteResult).to.have.property('status').to.eql("deleted");
265 | });
266 | });
267 | });
268 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "domino-nsf",
3 | "version": "0.3.1",
4 | "description": "Nodejs driver for Domino nsf databases",
5 | "homepage": "https://github.com/nthjelme/nodejs-domino",
6 | "scripts": {
7 | "commit": "git-cz",
8 | "test": "mocha index.test.js"
9 | },
10 | "dependencies": {},
11 | "keywords": [
12 | "database",
13 | "domino",
14 | "json",
15 | "nosql",
16 | "nsf"
17 | ],
18 | "os": [
19 | "win32",
20 | "linux"
21 | ],
22 | "cpu": [
23 | "ia32",
24 | "x64"
25 | ],
26 | "license": "MIT",
27 | "main": "index.js",
28 | "author": {
29 | "email": "nhjelme@gmail.com",
30 | "name": "Nils Tarjei Hjelme"
31 | },
32 | "maintainers": [
33 | {
34 | "name": "nhjelme",
35 | "email": "nhjelme@gmail.com"
36 | }
37 | ],
38 | "repository": {
39 | "type": "git",
40 | "url": "https://github.com/nthjelme/nodejs-domino.git"
41 | },
42 | "devDependencies": {
43 | "chai": "^3.5.0",
44 | "cz-conventional-changelog": "^1.2.0",
45 | "mocha": "^3.1.2",
46 | "nan": "^2.8.0"
47 | },
48 | "config": {
49 | "commitizen": {
50 | "path": "cz-conventional-changelog"
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/DataHelper.cc:
--------------------------------------------------------------------------------
1 | #include "DataHelper.h"
2 | #include
3 |
4 | void DataHelper::GetAPIError(STATUS api_error, char * error_text)
5 | {
6 | STATUS string_id = ERR(api_error);
7 | WORD text_len;
8 |
9 | /* Get the message for this IBM C API for Notes/Domino error code
10 | from the resource string table. */
11 |
12 | text_len = OSLoadString(NULLHANDLE,
13 | string_id,
14 | error_text,
15 | 200);
16 | return;
17 | }
18 |
19 | void DataHelper::ToNOTEID(const char *idStr,NOTEID * noteId) {
20 | if (strlen(idStr) == 8) {
21 | char id_buffer[9];
22 | strncpy(id_buffer,idStr,8);
23 | id_buffer[8] = '\0';
24 | *noteId = (DWORD)strtoul(id_buffer+8,NULL,16);
25 | }
26 | }
27 |
28 | void DataHelper::ToUNID(const char *unidStr, UNID * Unid) {
29 | if (strlen(unidStr) == 32) {
30 | char unid_buffer[33];
31 | strncpy(unid_buffer, unidStr, 32);
32 | unid_buffer[32] = '\0';
33 | if (strlen(unid_buffer) == 32)
34 | {
35 | /* Note part second, reading backwards in buffer */
36 | Unid->Note.Innards[0] = (DWORD)strtoul(unid_buffer + 24, NULL, 16);
37 | unid_buffer[24] = '\0';
38 | Unid->Note.Innards[1] = (DWORD)strtoul(unid_buffer + 16, NULL, 16);
39 | unid_buffer[16] = '\0';
40 |
41 | /* DB part first */
42 | Unid->File.Innards[0] = (DWORD)strtoul(unid_buffer + 8, NULL, 16);
43 | unid_buffer[8] = '\0';
44 | Unid->File.Innards[1] = (DWORD)strtoul(unid_buffer, NULL, 16);
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/src/DataHelper.h:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Domino addon for Node.js
3 | *
4 | * Copyright (c) 2016 Nils T. Hjelme
5 | *
6 | * The MIT License (MIT)
7 | *
8 | * Permission is hereby granted, free of charge, to any person obtaining a copy
9 | * of this software and associated documentation files (the "Software"), to deal
10 | * in the Software without restriction, including without limitation the rights
11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | * copies of the Software, and to permit persons to whom the Software is
13 | * furnished to do so, subject to the following conditions:
14 |
15 | * The above copyright notice and this permission notice shall be included in all
16 | * copies or substantial portions of the Software.
17 | *
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 | * SOFTWARE.
25 | *******************************************************************************/
26 |
27 | #ifndef DATA_HELPER_H_
28 | #define DATA_HELPER_H_
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include