1
+ /* Copyright (c) 2019, 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
+ * 207. dbObject8.js
20
+ *
21
+ * DESCRIPTION
22
+ * The test of examples/selectobject.js.
23
+ *
24
+ *****************************************************************************/
25
+ 'use strict' ;
26
+
27
+ const oracledb = require ( 'oracledb' ) ;
28
+ const should = require ( 'should' ) ;
29
+ const dbconfig = require ( './dbconfig.js' ) ;
30
+ const testsUtil = require ( './testsUtil.js' ) ;
31
+
32
+ describe ( '207. dbObject8.js' , ( ) => {
33
+
34
+ let conn ;
35
+ const TYPE1 = 'NODB_HARVEST_T' ;
36
+ const TYPE2 = 'NODB_FARM_T' ;
37
+ const TABLE = 'NODB_TAB_FARM' ;
38
+
39
+ before ( async ( ) => {
40
+ try {
41
+ conn = await oracledb . getConnection ( dbconfig ) ;
42
+
43
+ let sql = `CREATE OR REPLACE TYPE ${ TYPE1 } AS VARRAY(10) OF VARCHAR2(20)` ;
44
+ await conn . execute ( sql ) ;
45
+
46
+ sql =
47
+ `CREATE OR REPLACE TYPE ${ TYPE2 } AS OBJECT (
48
+ farmername VARCHAR2(20),
49
+ harvest ${ TYPE1 }
50
+ )` ;
51
+ await conn . execute ( sql ) ;
52
+
53
+ sql =
54
+ `CREATE TABLE ${ TABLE } (
55
+ id NUMBER,
56
+ farm ${ TYPE2 }
57
+ )` ;
58
+ let plsql = testsUtil . sqlCreateTable ( TABLE , sql ) ;
59
+ await conn . execute ( plsql ) ;
60
+
61
+ } catch ( err ) {
62
+ should . not . exist ( err ) ;
63
+ }
64
+ } ) ; // before()
65
+
66
+ after ( async ( ) => {
67
+ try {
68
+ let sql = `DROP TABLE ${ TABLE } PURGE` ;
69
+ await conn . execute ( sql ) ;
70
+
71
+ sql = `DROP TYPE ${ TYPE2 } FORCE` ;
72
+ await conn . execute ( sql ) ;
73
+
74
+ sql = `DROP TYPE ${ TYPE1 } FORCE` ;
75
+ await conn . execute ( sql ) ;
76
+
77
+ await conn . close ( ) ;
78
+ } catch ( err ) {
79
+ should . not . exist ( err ) ;
80
+ }
81
+ } ) ; // after()
82
+
83
+ it ( '207.1 examples/selectobject.js' , async ( ) => {
84
+
85
+ try {
86
+ const FarmType = await conn . getDbObjectClass ( TYPE2 ) ;
87
+ // Farm Type
88
+ should . strictEqual ( FarmType . prototype . name , TYPE2 ) ;
89
+ ( FarmType . prototype . isCollection ) . should . be . false ( ) ;
90
+
91
+ // Nested type
92
+ should . strictEqual (
93
+ FarmType . prototype . attributes . HARVEST . typeClass . prototype . name ,
94
+ TYPE1
95
+ ) ;
96
+ ( FarmType . prototype . attributes . HARVEST . typeClass . prototype . isCollection )
97
+ . should . be . true ( ) ;
98
+
99
+ // Insert Method 1: pass a JavaScript object to the constructor
100
+ let crops = [ ] ;
101
+ crops [ 0 ] = [ 'Apples' , 'Pears' , 'Peaches' ] ;
102
+ const farm1 = new FarmType (
103
+ {
104
+ FARMERNAME : 'MacDonald' ,
105
+ HARVEST : crops [ 0 ]
106
+ }
107
+ ) ;
108
+ await conn . execute (
109
+ `INSERT INTO ${ TABLE } (id, farm) VALUES (:id, :f)` ,
110
+ { id : 1 , f : farm1 }
111
+ ) ;
112
+
113
+ // Insert Method 2: set each attribute individually
114
+
115
+ // A nested type
116
+ const HarvestType = FarmType . prototype . attributes . HARVEST . typeClass ;
117
+
118
+ const farm2 = new FarmType ( ) ;
119
+ farm2 . FARMERNAME = 'Giles' ;
120
+ farm2 . HARVEST = new HarvestType ( [ 'carrots' , 'peas' ] ) ;
121
+ farm2 . HARVEST . trim ( 1 ) ; // whoops! no peas
122
+ farm2 . HARVEST . append ( 'tomatoes' ) ; // extend the collection
123
+ // console.log(farm2.HARVEST.getValues());
124
+ crops [ 1 ] = farm2 . HARVEST . getValues ( ) ;
125
+ should . deepEqual ( crops [ 1 ] , [ 'carrots' , 'tomatoes' ] ) ;
126
+
127
+ await conn . execute (
128
+ `INSERT INTO ${ TABLE } (id, farm) VALUES (:id, :f)` ,
129
+ { id : 2 , f : farm2 }
130
+ ) ;
131
+
132
+ //
133
+ // Insert Method 3: use the prototype object for the bind 'type',
134
+ // and supply a JavaScript object directly for the 'val'
135
+ //
136
+
137
+ crops [ 2 ] = [ 'pepper' , 'cinnamon' , 'nutmeg' ] ;
138
+
139
+ await conn . execute (
140
+ `INSERT INTO ${ TABLE } (id, farm) VALUES (:id, :f)` ,
141
+ { id : 3 ,
142
+ f : {
143
+ type : FarmType , // pass the prototype object
144
+ val : { // a JavaScript object that maps to the DB object
145
+ FARMERNAME : 'Smith' ,
146
+ HARVEST : crops [ 2 ]
147
+ }
148
+ }
149
+ }
150
+ ) ;
151
+
152
+ //
153
+ // Insert Method 4: use the Oracle type name.
154
+ // Note: use a fully qualified type name when possible.
155
+ //
156
+ crops [ 3 ] = [ 'flowers' , 'seedlings' ] ;
157
+ await conn . execute (
158
+ `INSERT INTO ${ TABLE } (id, farm) VALUES (:id, :f)` ,
159
+ { id : 4 ,
160
+ f : {
161
+ type : TYPE2 , // the name of the database type, case sensitive
162
+ val : { // a JavaScript object that maps to the DB object
163
+ FARMERNAME : 'Boy' ,
164
+ HARVEST : crops [ 3 ]
165
+ }
166
+ }
167
+ }
168
+ ) ;
169
+
170
+ // Querying
171
+
172
+ let result = await conn . execute (
173
+ `SELECT id, farm FROM ${ TABLE } ` ,
174
+ [ ] ,
175
+ { outFormat : oracledb . OUT_FORMAT_OBJECT }
176
+ ) ;
177
+
178
+ const names = [ 'MacDonald' , 'Giles' , 'Smith' , 'Boy' ] ;
179
+ let i = 0 ;
180
+ for ( const row of result . rows ) {
181
+
182
+ const farm = row . FARM ; // a DbObject for the named Oracle type
183
+
184
+ should . strictEqual ( farm . FARMERNAME , names [ i ] ) ;
185
+
186
+ const harvests = farm . HARVEST . getValues ( ) ;
187
+ should . deepEqual ( harvests , crops [ i ] ) ;
188
+ i ++ ;
189
+ }
190
+
191
+ } catch ( err ) {
192
+ should . not . exist ( err ) ;
193
+ }
194
+ } ) ; // 207.1
195
+ } ) ;
0 commit comments