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