1 /*
2  Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights
3  reserved.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License, version 2.0,
7  as published by the Free Software Foundation.
8 
9  This program is also distributed with certain software (including
10  but not limited to OpenSSL) that is licensed under separate terms,
11  as designated in a particular file or component or in included license
12  documentation.  The authors of MySQL hereby grant you an additional
13  permission to link the program and your derivative works with the
14  separately licensed software that they have included with MySQL.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  GNU General Public License, version 2.0, for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24  02110-1301  USA
25 */
26 
27 
28 #include <NdbApi.hpp>
29 
30 #include "adapter_global.h"
31 #include "js_wrapper_macros.h"
32 #include "Record.h"
33 #include "NativeMethodCall.h"
34 
35 #include "NdbTypeEncoders.h"
36 
37 using namespace v8;
38 
39 Handle<Value> getColumnOffset_wrapper(const Arguments &);
40 Handle<Value> getBufferSize_wrapper(const Arguments &);
41 Handle<Value> setNull_wrapper(const Arguments &);
42 Handle<Value> setNotNull_wrapper(const Arguments &);
43 Handle<Value> isNull_wrapper(const Arguments &);
44 Handle<Value> record_encoderRead(const Arguments &);
45 Handle<Value> record_encoderWrite(const Arguments &);
46 
47 class RecordEnvelopeClass : public Envelope {
48 public:
RecordEnvelopeClass()49   RecordEnvelopeClass() : Envelope("Record") {
50     DEFINE_JS_FUNCTION(Envelope::stencil, "getColumnOffset", getColumnOffset_wrapper);
51     DEFINE_JS_FUNCTION(Envelope::stencil, "getBufferSize", getBufferSize_wrapper);
52     DEFINE_JS_FUNCTION(Envelope::stencil, "setNull", setNull_wrapper);
53     DEFINE_JS_FUNCTION(Envelope::stencil, "isNull", isNull_wrapper);
54     DEFINE_JS_FUNCTION(Envelope::stencil, "encoderRead", record_encoderRead);
55     DEFINE_JS_FUNCTION(Envelope::stencil, "encoderWrite", record_encoderWrite);
56   }
57 };
58 
59 RecordEnvelopeClass RecordEnvelope;
60 
61 
62 /****  CALL THIS FROM C++ CODE TO CREATE A WRAPPED RECORD OBJECT.
63 *****/
Record_Wrapper(const Record * rec)64 Handle<Value> Record_Wrapper(const Record *rec) {
65   HandleScope scope;
66 
67   Local<Object> js_record = RecordEnvelope.newWrapper();
68   wrapPointerInObject(rec, RecordEnvelope, js_record);
69   freeFromGC(rec, js_record);
70   return scope.Close(js_record);
71 }
72 
73 
getColumnOffset_wrapper(const Arguments & args)74 Handle<Value> getColumnOffset_wrapper(const Arguments &args) {
75   DEBUG_MARKER(UDEB_DETAIL);
76   HandleScope scope;
77 
78   REQUIRE_ARGS_LENGTH(1);
79 
80   typedef NativeConstMethodCall_1_<size_t, const Record, int> NCALL;
81 
82   NCALL ncall(& Record::getColumnOffset, args);
83   ncall.run();
84 
85   return scope.Close(ncall.jsReturnVal());
86 }
87 
88 
getBufferSize_wrapper(const Arguments & args)89 Handle<Value> getBufferSize_wrapper(const Arguments &args) {
90   DEBUG_MARKER(UDEB_DETAIL);
91   HandleScope scope;
92 
93   REQUIRE_ARGS_LENGTH(0);
94 
95   typedef NativeConstMethodCall_0_<size_t, const Record> NCALL;
96 
97   NCALL ncall(& Record::getBufferSize, args);
98   ncall.run();
99 
100   return scope.Close(ncall.jsReturnVal());
101 }
102 
setNull_wrapper(const Arguments & args)103 Handle<Value> setNull_wrapper(const Arguments &args) {
104   DEBUG_MARKER(UDEB_DEBUG);
105   HandleScope scope;
106 
107   REQUIRE_ARGS_LENGTH(2);
108 
109   typedef NativeVoidConstMethodCall_2_<const Record, int, char *> NCALL;
110 
111   NCALL ncall(& Record::setNull, args);
112   ncall.run();
113 
114   return scope.Close(ncall.jsReturnVal());
115 }
116 
isNull_wrapper(const Arguments & args)117 Handle<Value> isNull_wrapper(const Arguments &args) {
118   DEBUG_MARKER(UDEB_DETAIL);
119   HandleScope scope;
120 
121   REQUIRE_ARGS_LENGTH(2);
122 
123   typedef NativeConstMethodCall_2_<uint32_t, const Record, int, char *> NCALL;
124 
125   NCALL ncall(& Record::isNull, args);
126   ncall.run();
127 
128   return scope.Close(ncall.jsReturnVal());
129 }
130 
131 
132 /* read(columnNumber, buffer)
133 */
record_encoderRead(const Arguments & args)134 Handle<Value> record_encoderRead(const Arguments & args) {
135   HandleScope scope;
136   const Record * record = unwrapPointer<Record *>(args.Holder());
137   int columnNumber = args[0]->Uint32Value();
138   char * buffer = node::Buffer::Data(args[1]->ToObject());
139 
140   const NdbDictionary::Column * col = record->getColumn(columnNumber);
141   size_t offset = record->getColumnOffset(columnNumber);
142 
143   const NdbTypeEncoder * encoder = getEncoderForColumn(col);
144 
145   return encoder->read(col, buffer, offset);
146 }
147 
148 
149 /* write(columnNumber, buffer, value)
150 */
record_encoderWrite(const Arguments & args)151 Handle<Value> record_encoderWrite(const Arguments & args) {
152   HandleScope scope;
153 
154   const Record * record = unwrapPointer<const Record *>(args.Holder());
155   int columnNumber = args[0]->Uint32Value();
156   char * buffer = node::Buffer::Data(args[1]->ToObject());
157 
158   record->setNotNull(columnNumber, buffer);
159 
160   const NdbDictionary::Column * col = record->getColumn(columnNumber);
161   size_t offset = record->getColumnOffset(columnNumber);
162 
163   const NdbTypeEncoder * encoder = getEncoderForColumn(col);
164   Handle<Value> error = encoder->write(col, args[2], buffer, offset);
165 
166   return scope.Close(error);
167 }
168 
169