Skip to content

Commit 00e3ed6

Browse files
committed
Add new source file
1 parent ed44444 commit 00e3ed6

File tree

1 file changed

+257
-0
lines changed

1 file changed

+257
-0
lines changed

src/njsJsContext.c

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
// Copyright (c) 2025, Oracle and/or its affiliates.
2+
3+
//-----------------------------------------------------------------------------
4+
//
5+
// This software is dual-licensed to you under the Universal Permissive License
6+
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
7+
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
8+
// either license.
9+
//
10+
// If you elect to accept the software under the Apache License, Version 2.0,
11+
// the following applies:
12+
//
13+
// Licensed under the Apache License, Version 2.0 (the "License");
14+
// you may not use this file except in compliance with the License.
15+
// You may obtain a copy of the License at
16+
//
17+
// https://www.apache.org/licenses/LICENSE-2.0
18+
//
19+
// Unless required by applicable law or agreed to in writing, software
20+
// distributed under the License is distributed on an "AS IS" BASIS,
21+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22+
// See the License for the specific language governing permissions and
23+
// limitations under the License.
24+
//
25+
// NAME
26+
// njsJsContext.c
27+
//
28+
// DESCRIPTION
29+
// Implementation of njsJsContext methods to call JS methods inside C.
30+
//
31+
//-----------------------------------------------------------------------------
32+
33+
#include "njsModule.h"
34+
35+
//-----------------------------------------------------------------------------
36+
// njsJsContext_populate()
37+
// Sets the JavaScript values on the njsContext structure. These are a number
38+
// of constructors and also the JavaScript object that is "this" for the method
39+
// that is currently being executed.
40+
//-----------------------------------------------------------------------------
41+
bool njsJsContext_populate(napi_env env, njsModuleGlobals *globals,
42+
njsJsContext *jsContext)
43+
{
44+
// acquire the LOB constructor
45+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
46+
globals->jsLobConstructor, &jsContext->jsLobConstructor))
47+
48+
// acquire the result set constructor
49+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
50+
globals->jsResultSetConstructor,
51+
&jsContext->jsResultSetConstructor))
52+
53+
// acquire the base database object constructor
54+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
55+
globals->jsDbObjectConstructor,
56+
&jsContext->jsDbObjectConstructor))
57+
58+
// acquire the _getDateComponents() function
59+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
60+
globals->jsGetDateComponentsFn,
61+
&jsContext->jsGetDateComponentsFn))
62+
63+
// acquire the _makeDate() function
64+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
65+
globals->jsMakeDateFn, &jsContext->jsMakeDateFn))
66+
67+
// acquire the _decodeVector function
68+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
69+
globals->jsDecodeVectorFn, &jsContext->jsDecodeVectorFn))
70+
71+
// acquire the _encodeVector function
72+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
73+
globals->jsEncodeVectorFn, &jsContext->jsEncodeVectorFn))
74+
75+
// acquire the JsonId constructor
76+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
77+
globals->jsJsonIdConstructor, &jsContext->jsJsonIdConstructor))
78+
79+
// acquire the SparseVector constructor
80+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
81+
globals->jsSparseVectorConstructor,
82+
&jsContext->jsSparseVectorConstructor))
83+
84+
// acquire the IntervalYM constructor
85+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
86+
globals->jsIntervalYMConstructor,
87+
&jsContext->jsIntervalYMConstructor))
88+
89+
// acquire the IntervalDS constructor
90+
NJS_CHECK_NAPI(env, napi_get_reference_value(env,
91+
globals->jsIntervalDSConstructor,
92+
&jsContext->jsIntervalDSConstructor))
93+
94+
return true;
95+
}
96+
97+
98+
//-----------------------------------------------------------------------------
99+
// njsJsContext_getJsonNodeValue()
100+
// Return an appropriate JavaScript value for the JSON node.
101+
//-----------------------------------------------------------------------------
102+
bool njsJsContext_getJsonNodeValue(njsJsContext *jsContext, dpiJsonNode *node,
103+
napi_env env, napi_value *value)
104+
{
105+
napi_value key, temp;
106+
dpiJsonArray *array;
107+
dpiJsonObject *obj;
108+
void *destData = NULL;
109+
size_t byteLength = 0;
110+
double temp_double;
111+
uint32_t i;
112+
napi_value global, vectorBytes, arrBuf;
113+
114+
// null is a special case
115+
if (node->nativeTypeNum == DPI_NATIVE_TYPE_NULL) {
116+
NJS_CHECK_NAPI(env, napi_get_null(env, value))
117+
return true;
118+
}
119+
120+
// handle the other types supported in JSON nodes
121+
switch (node->oracleTypeNum) {
122+
case DPI_ORACLE_TYPE_JSON_ARRAY:
123+
array = &node->value->asJsonArray;
124+
NJS_CHECK_NAPI(env, napi_create_array_with_length(env,
125+
array->numElements, value))
126+
for (i = 0; i < array->numElements; i++) {
127+
if (!njsJsContext_getJsonNodeValue(jsContext, &array->elements[i],
128+
env, &temp))
129+
return false;
130+
NJS_CHECK_NAPI(env, napi_set_element(env, *value, i, temp))
131+
}
132+
return true;
133+
case DPI_ORACLE_TYPE_JSON_OBJECT:
134+
obj = &node->value->asJsonObject;
135+
NJS_CHECK_NAPI(env, napi_create_object(env, value))
136+
for (i = 0; i< obj->numFields; i++) {
137+
NJS_CHECK_NAPI(env, napi_create_string_utf8(env,
138+
obj->fieldNames[i], obj->fieldNameLengths[i], &key))
139+
if (!njsJsContext_getJsonNodeValue(jsContext, &obj->fields[i],
140+
env, &temp))
141+
return false;
142+
NJS_CHECK_NAPI(env, napi_set_property(env, *value, key, temp))
143+
}
144+
return true;
145+
case DPI_ORACLE_TYPE_VARCHAR:
146+
NJS_CHECK_NAPI(env, napi_create_string_utf8(env,
147+
node->value->asBytes.ptr, node->value->asBytes.length,
148+
value))
149+
return true;
150+
case DPI_ORACLE_TYPE_RAW:
151+
NJS_CHECK_NAPI(env, napi_create_buffer_copy(env,
152+
node->value->asBytes.length, node->value->asBytes.ptr,
153+
NULL, value))
154+
return true;
155+
case DPI_ORACLE_TYPE_NUMBER:
156+
temp_double = (node->nativeTypeNum == DPI_NATIVE_TYPE_DOUBLE) ?
157+
node->value->asDouble : node->value->asFloat;
158+
NJS_CHECK_NAPI(env, napi_create_double(env, temp_double, value))
159+
return true;
160+
case DPI_ORACLE_TYPE_DATE:
161+
case DPI_ORACLE_TYPE_TIMESTAMP:
162+
return njsUtils_getDateValue(node->oracleTypeNum, env,
163+
jsContext->jsMakeDateFn, &node->value->asTimestamp, value);
164+
return true;
165+
case DPI_ORACLE_TYPE_BOOLEAN:
166+
NJS_CHECK_NAPI(env, napi_get_boolean(env, node->value->asBoolean,
167+
value))
168+
return true;
169+
case DPI_ORACLE_TYPE_INTERVAL_YM:
170+
return njsJsContext_getIntervalYM(jsContext,
171+
&(node->value->asIntervalYM), env, value);
172+
case DPI_ORACLE_TYPE_INTERVAL_DS:
173+
return njsJsContext_getIntervalDS(jsContext,
174+
&(node->value->asIntervalDS), env, value);
175+
case DPI_ORACLE_TYPE_VECTOR:
176+
NJS_CHECK_NAPI(env, napi_get_global(env, &global))
177+
NJS_CHECK_NAPI(env, napi_create_buffer_copy(env,
178+
node->value->asBytes.length, node->value->asBytes.ptr,
179+
NULL, &vectorBytes))
180+
NJS_CHECK_NAPI(env, napi_call_function(env, global,
181+
jsContext->jsDecodeVectorFn, 1, &vectorBytes, value))
182+
return true;
183+
case DPI_ORACLE_TYPE_JSON_ID:
184+
byteLength = node->value->asBytes.length;
185+
NJS_CHECK_NAPI(env, napi_create_arraybuffer(env,
186+
byteLength, &destData, &arrBuf))
187+
memcpy(destData, node->value->asBytes.ptr, byteLength);
188+
NJS_CHECK_NAPI(env, napi_new_instance(env,
189+
jsContext->jsJsonIdConstructor, 1, &arrBuf, value))
190+
return true;
191+
192+
default:
193+
break;
194+
}
195+
196+
return njsUtils_throwUnsupportedDataTypeInJson(env,
197+
node->oracleTypeNum);
198+
}
199+
200+
201+
//-----------------------------------------------------------------------------
202+
// njsJsContext_getIntervalYM()
203+
// Returns the appropriate IntervalYM JavaScript object for the Interval
204+
// year-to-month type. At this point it is known that the Javascript
205+
// attributes are integers and that the variable can support it.
206+
//-----------------------------------------------------------------------------
207+
bool njsJsContext_getIntervalYM(njsJsContext *jsContext, dpiIntervalYM *data,
208+
napi_env env, napi_value *value)
209+
{
210+
napi_value temp, intervalYMTempObj;
211+
212+
NJS_CHECK_NAPI(env, napi_create_object(env, &intervalYMTempObj))
213+
NJS_CHECK_NAPI(env, napi_create_int32(env, data->years, &temp))
214+
NJS_CHECK_NAPI(env, napi_set_named_property(env, intervalYMTempObj,
215+
"years", temp))
216+
NJS_CHECK_NAPI(env, napi_create_int32(env, data->months, &temp))
217+
NJS_CHECK_NAPI(env, napi_set_named_property(env, intervalYMTempObj,
218+
"months", temp))
219+
NJS_CHECK_NAPI(env, napi_new_instance(env,
220+
jsContext->jsIntervalYMConstructor, 1, &intervalYMTempObj, value))
221+
222+
return true;
223+
}
224+
225+
226+
//-----------------------------------------------------------------------------
227+
// njsJsContext_getIntervalDS()
228+
// Returns the appropriate IntervalDS JavaScript object for the Interval
229+
// day-to-second type. At this point it is known that the Javascript
230+
// attributes are integers and that the variable can support it.
231+
//-----------------------------------------------------------------------------
232+
bool njsJsContext_getIntervalDS(njsJsContext *jsContext, dpiIntervalDS *data,
233+
napi_env env, napi_value *value)
234+
{
235+
napi_value temp, intervalDSTempObj;
236+
237+
NJS_CHECK_NAPI(env, napi_create_object(env, &intervalDSTempObj))
238+
NJS_CHECK_NAPI(env, napi_create_int32(env, data->days, &temp))
239+
NJS_CHECK_NAPI(env, napi_set_named_property(env, intervalDSTempObj,
240+
"days", temp))
241+
NJS_CHECK_NAPI(env, napi_create_int32(env, data->hours, &temp))
242+
NJS_CHECK_NAPI(env, napi_set_named_property(env, intervalDSTempObj,
243+
"hours", temp))
244+
NJS_CHECK_NAPI(env, napi_create_int32(env, data->minutes, &temp))
245+
NJS_CHECK_NAPI(env, napi_set_named_property(env, intervalDSTempObj,
246+
"minutes", temp))
247+
NJS_CHECK_NAPI(env, napi_create_int32(env, data->seconds, &temp))
248+
NJS_CHECK_NAPI(env, napi_set_named_property(env, intervalDSTempObj,
249+
"seconds", temp))
250+
NJS_CHECK_NAPI(env, napi_create_int32(env, data->fseconds, &temp))
251+
NJS_CHECK_NAPI(env, napi_set_named_property(env, intervalDSTempObj,
252+
"fseconds", temp))
253+
NJS_CHECK_NAPI(env, napi_new_instance(env,
254+
jsContext->jsIntervalDSConstructor, 1, &intervalDSTempObj, value))
255+
256+
return true;
257+
}

0 commit comments

Comments
 (0)