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 #include <NdbApi.hpp>
26
27 #include "adapter_global.h"
28 #include "js_wrapper_macros.h"
29 #include "Record.h"
30 #include "NativeMethodCall.h"
31 #include "NativeCFunctionCall.h"
32 #include "NdbWrapperErrors.h"
33
34 using namespace v8;
35
36 // FIXME: All of this should be on SessionImpl with Ndb object not directly
37 // exposed to JavaScript
38
39 V8WrapperFn getAutoIncValue,
40 closeNdb,
41 getStatistics,
42 getConnectionStatistics;
43
44 class NdbEnvelopeClass : public Envelope {
45 public:
NdbEnvelopeClass()46 NdbEnvelopeClass() : Envelope("Ndb") {
47 EscapableHandleScope scope(v8::Isolate::GetCurrent());
48 addMethod("getNdbError", getNdbError<Ndb>);
49 addMethod("close", closeNdb);
50 addMethod("getStatistics", getStatistics);
51 addMethod("getConnectionStatistics", getConnectionStatistics);
52 }
53 };
54
55 NdbEnvelopeClass NdbEnvelope;
56
Ndb_Wrapper(Ndb * ndb)57 Local<Value> Ndb_Wrapper(Ndb *ndb) {
58 return NdbEnvelope.wrap(ndb);
59 }
60
61 /* Ndb constructor.
62 create_ndb(Ndb_cluster_connection, databaseName, callback)
63 The constructor is wrapped in a call that also calls ndb->init().
64 */
async_create_ndb(Ndb_cluster_connection * conn,const char * db)65 Ndb * async_create_ndb(Ndb_cluster_connection *conn, const char *db) {
66 Ndb *ndb = new Ndb(conn, db);
67 DEBUG_PRINT("Created Ndb %p", ndb);
68 if(ndb) ndb->init();
69 return ndb;
70 }
71
create_ndb(const Arguments & args)72 void create_ndb(const Arguments &args) {
73 REQUIRE_ARGS_LENGTH(3);
74
75 typedef NativeCFunctionCall_2_<Ndb *, Ndb_cluster_connection *, const char *> MCALL;
76 MCALL * mcallptr = new MCALL(& async_create_ndb, args);
77 mcallptr->wrapReturnValueAs(& NdbEnvelope);
78 mcallptr->runAsync();
79 args.GetReturnValue().SetUndefined();
80 }
81
82
83 /* getAutoIncrementValue(ndb, table, batch_size, callback);
84 We can't map Ndb::getAutoIncrementValue() directly due to in/out param.
85 The JS Wrapper function will simply return 0 on error.
86 */
getAutoInc(Ndb * ndb,const NdbDictionary::Table * table,uint32_t batch)87 Uint64 getAutoInc(Ndb *ndb, const NdbDictionary::Table * table, uint32_t batch) {
88 Uint64 autoinc;
89 DEBUG_PRINT("getAutoIncrementValue %p", ndb);
90 int r = ndb->getAutoIncrementValue(table, autoinc, batch);
91 if(r == -1) autoinc = 0;
92 return autoinc;
93 }
94
getAutoIncValue(const Arguments & args)95 void getAutoIncValue(const Arguments &args) {
96 DEBUG_MARKER(UDEB_DEBUG);
97 REQUIRE_ARGS_LENGTH(4);
98 typedef NativeCFunctionCall_3_<Uint64, Ndb *, const NdbDictionary::Table *,
99 uint32_t> MCALL;
100 MCALL * mcallptr = new MCALL(& getAutoInc, args);
101 mcallptr->runAsync();
102 args.GetReturnValue().SetUndefined();
103 }
104
105
getStatistics(const Arguments & args)106 void getStatistics(const Arguments &args) {
107 EscapableHandleScope scope(args.GetIsolate());
108 Ndb *ndb = unwrapPointer<Ndb *>(args.Holder());
109
110 Local<Object> stats = Object::New(args.GetIsolate());
111 for(int i = 0 ; i < Ndb::NumClientStatistics ; i ++) {
112 stats->Set(String::NewFromUtf8(args.GetIsolate(), ndb->getClientStatName(i)),
113 Number::New(args.GetIsolate(), ndb->getClientStat(i)));
114 }
115
116 args.GetReturnValue().Set(scope.Escape(stats));
117 }
118
119
getConnectionStatistics(const Arguments & args)120 void getConnectionStatistics(const Arguments &args) {
121 EscapableHandleScope scope(args.GetIsolate());
122 Uint64 ndb_stats[Ndb::NumClientStatistics];
123
124 Ndb *ndb = unwrapPointer<Ndb *>(args.Holder());
125 Ndb_cluster_connection & c = ndb->get_ndb_cluster_connection();
126
127 c.collect_client_stats(ndb_stats, Ndb::NumClientStatistics);
128
129 Local<Object> stats = Object::New(args.GetIsolate());
130 for(int i = 0 ; i < Ndb::NumClientStatistics ; i ++) {
131 stats->Set(String::NewFromUtf8(args.GetIsolate(), ndb->getClientStatName(i)),
132 Number::New(args.GetIsolate(), ndb_stats[i]));
133 }
134
135 args.GetReturnValue().Set(scope.Escape(stats));
136 }
137
closeNdb(const Arguments & args)138 void closeNdb(const Arguments &args) {
139 DEBUG_MARKER(UDEB_DETAIL);
140 typedef NativeDestructorCall<Ndb> MCALL;
141 MCALL * mcallptr = new MCALL(args);
142 mcallptr->runAsync();
143 args.GetReturnValue().SetUndefined();
144 }
145
146
NdbWrapper_initOnLoad(Handle<Object> target)147 void NdbWrapper_initOnLoad(Handle<Object> target) {
148 DEFINE_JS_FUNCTION(target, "getAutoIncrementValue", getAutoIncValue);
149 DEFINE_JS_FUNCTION(target, "create_ndb", create_ndb);
150 }
151