1 | /* |
2 | * Copyright 2008-2018 Aerospike, Inc. |
3 | * |
4 | * Portions may be licensed to Aerospike, Inc. under one or more contributor |
5 | * license agreements. |
6 | * |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
8 | * use this file except in compliance with the License. You may obtain a copy of |
9 | * the License at 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. See the |
14 | * License for the specific language governing permissions and limitations under |
15 | * the License. |
16 | */ |
17 | #include <aerospike/as_std.h> |
18 | |
19 | // This system lua code in the lua-core repo have been converted to these strings. |
20 | |
21 | const char as_lua_as[] = |
22 | "Map = Map or getmetatable(map())\n" |
23 | "List = List or getmetatable(list())\n" |
24 | "Bytes = Bytes or getmetatable(bytes())\n" |
25 | "function list.clone(l)\n" |
26 | " local ll = {}\n" |
27 | " for v in list.iterator(l) do\n" |
28 | " table.insert(ll, v)\n" |
29 | " end\n" |
30 | " return list(ll)\n" |
31 | "end\n" |
32 | "function list.merge(l1, l2)\n" |
33 | " local ll = {}\n" |
34 | " for v in list.iterator(l1) do\n" |
35 | " table.insert(ll,v)\n" |
36 | " end\n" |
37 | " for v in list.iterator(l2) do\n" |
38 | " table.insert(ll, v)\n" |
39 | " end\n" |
40 | " return list(ll)\n" |
41 | "end\n" |
42 | "function map.merge(m1,m2,f)\n" |
43 | " local mm = {}\n" |
44 | " for k,v in map.pairs(m1) do\n" |
45 | " mm[k] = v\n" |
46 | " end\n" |
47 | " for k,v in map.pairs(m2) do\n" |
48 | " mm[k] = (mm[k] and f and type(f) == 'function' and f(m1[k],m2[k])) or v\n" |
49 | " end\n" |
50 | " return map(mm, map.size(m1) + map.size(m2))\n" |
51 | "end\n" |
52 | "function map.diff(m1,m2)\n" |
53 | " local mm = {}\n" |
54 | " for k,v in map.pairs(m1) do\n" |
55 | " if not m2[k] then\n" |
56 | " mm[k] = v\n" |
57 | " end\n" |
58 | " end\n" |
59 | " for k,v in map.pairs(m2) do\n" |
60 | " if not m1[k] then\n" |
61 | " mm[k] = v\n" |
62 | " end\n" |
63 | " end\n" |
64 | " return map(mm, map.size(m1) + map.size(m2))\n" |
65 | "end\n" |
66 | "function map.clone(m)\n" |
67 | " local mm = {}\n" |
68 | " for k,v in map.pairs(m) do\n" |
69 | " mm[k] = v\n" |
70 | " end\n" |
71 | " return map(mm, map.size(m))\n" |
72 | "end\n" |
73 | "function math.sum(a,b) \n" |
74 | " return a + b\n" |
75 | "end\n" |
76 | "function math.product(a, b)\n" |
77 | " return a * b\n" |
78 | "end\n" |
79 | ; |
80 | |
81 | size_t as_lua_as_size = sizeof(as_lua_as); |
82 | |
83 | const char as_lua_stream_ops[] = |
84 | "local function check_limit(v)\n" |
85 | " return type(v) == 'number' and v >= 1000\n" |
86 | "end\n" |
87 | "local function clone_table(t)\n" |
88 | " local out = {}\n" |
89 | " for k,v in pairs(t) do\n" |
90 | " out[k] = v\n" |
91 | " end\n" |
92 | " return out\n" |
93 | "end\n" |
94 | "local function clone(v)\n" |
95 | " local t = type(v)\n" |
96 | " if t == 'number' then\n" |
97 | " return v\n" |
98 | " elseif t == 'string' then\n" |
99 | " return v\n" |
100 | " elseif t == 'boolean' then\n" |
101 | " return v\n" |
102 | " elseif t == 'table' then\n" |
103 | " return clone_table(v)\n" |
104 | " elseif t == 'userdata' then\n" |
105 | " if getmetatable(v) == Map then\n" |
106 | " return map.clone(v)\n" |
107 | " elseif getmetatable(v) == List then\n" |
108 | " return list.clone(v)\n" |
109 | " end\n" |
110 | " return nil\n" |
111 | " end\n" |
112 | " return v\n" |
113 | "end\n" |
114 | "function filter( next, p )\n" |
115 | " local done = false\n" |
116 | " return function()\n" |
117 | " if done then return nil end\n" |
118 | " for a in next do\n" |
119 | " if p(a) then\n" |
120 | " return a\n" |
121 | " end\n" |
122 | " end\n" |
123 | " done = true\n" |
124 | " return nil\n" |
125 | " end\n" |
126 | "end\n" |
127 | "function transform( next, f )\n" |
128 | " local done = false\n" |
129 | " return function()\n" |
130 | " if done then return nil end\n" |
131 | " local a = next()\n" |
132 | " if a ~= nil then\n" |
133 | " return f(a)\n" |
134 | " end\n" |
135 | " done = true;\n" |
136 | " return nil\n" |
137 | " end\n" |
138 | "end\n" |
139 | "function reduce( next, f )\n" |
140 | " local done = false\n" |
141 | " return function()\n" |
142 | " if done then return nil end\n" |
143 | " local a = next()\n" |
144 | " if a ~= nil then\n" |
145 | " for b in next do\n" |
146 | " a = f(a,b)\n" |
147 | " end\n" |
148 | " end\n" |
149 | " done = true\n" |
150 | " return a\n" |
151 | " end\n" |
152 | "end\n" |
153 | "function aggregate( next, init, f )\n" |
154 | " local done = false\n" |
155 | " return function()\n" |
156 | " if done then return nil end\n" |
157 | " local a = clone(init)\n" |
158 | " for b in next do\n" |
159 | " a = f(a,b)\n" |
160 | " if check_limit(a) then\n" |
161 | " return a\n" |
162 | " end\n" |
163 | " end\n" |
164 | " done = true\n" |
165 | " return a\n" |
166 | " end\n" |
167 | "end\n" |
168 | "function stream_iterator(s)\n" |
169 | " local done = false\n" |
170 | " return function()\n" |
171 | " if done then return nil end\n" |
172 | " local v = stream.read(s)\n" |
173 | " if v == nil then\n" |
174 | " done = true\n" |
175 | " end\n" |
176 | " return v;\n" |
177 | " end\n" |
178 | "end\n" |
179 | "StreamOps = {}\n" |
180 | "StreamOps_mt = { __index = StreamOps }\n" |
181 | "local SCOPE_SERVER = 1\n" |
182 | "local SCOPE_CLIENT = 2\n" |
183 | "local SCOPE_EITHER = 3\n" |
184 | "local SCOPE_BOTH = 4\n" |
185 | "function StreamOps_create()\n" |
186 | " local self = {}\n" |
187 | " setmetatable(self, StreamOps_mt)\n" |
188 | " self.ops = {}\n" |
189 | " return self\n" |
190 | "end\n" |
191 | "function StreamOps_apply(stream, ops, i, n)\n" |
192 | " i = i or 1\n" |
193 | " n = n or #ops\n" |
194 | " if i > n then return stream end\n" |
195 | " local op = ops[i]\n" |
196 | " local s = op.func(stream, unpack(op.args)) or stream\n" |
197 | " return StreamOps_apply(s, ops, i + 1, n)\n" |
198 | "end\n" |
199 | "function StreamOps_select(stream_ops, scope)\n" |
200 | " local server_ops = {}\n" |
201 | " local client_ops = {}\n" |
202 | " local phase = SCOPE_SERVER\n" |
203 | " for i,op in ipairs(stream_ops) do\n" |
204 | " if phase == SCOPE_SERVER then\n" |
205 | " if op.scope == SCOPE_SERVER then\n" |
206 | " table.insert(server_ops, op)\n" |
207 | " elseif op.scope == SCOPE_EITHER then\n" |
208 | " table.insert(server_ops, op)\n" |
209 | " elseif op.scope == SCOPE_BOTH then\n" |
210 | " table.insert(server_ops, op)\n" |
211 | " table.insert(client_ops, op)\n" |
212 | " phase = SCOPE_CLIENT\n" |
213 | " end\n" |
214 | " elseif phase == SCOPE_CLIENT then\n" |
215 | " table.insert(client_ops, op)\n" |
216 | " end \n" |
217 | " end\n" |
218 | " if scope == SCOPE_CLIENT then\n" |
219 | " return client_ops\n" |
220 | " else\n" |
221 | " return server_ops\n" |
222 | " end\n" |
223 | "end\n" |
224 | "function StreamOps:aggregate(...)\n" |
225 | " table.insert(self.ops, { scope = SCOPE_SERVER, name = \"aggregate\", func = aggregate, args = {...}})\n" |
226 | " return self\n" |
227 | "end\n" |
228 | "function StreamOps:reduce(...)\n" |
229 | " table.insert(self.ops, { scope = SCOPE_BOTH, name = \"reduce\", func = reduce, args = {...}})\n" |
230 | " return self\n" |
231 | "end\n" |
232 | "function StreamOps:map(...)\n" |
233 | " table.insert(self.ops, { scope = SCOPE_EITHER, name = \"map\", func = transform, args = {...}})\n" |
234 | " return self\n" |
235 | "end\n" |
236 | "function StreamOps:filter(...)\n" |
237 | " table.insert(self.ops, { scope = SCOPE_EITHER, name = \"filter\", func = filter, args = {...}})\n" |
238 | " return self\n" |
239 | "end\n" |
240 | "function StreamOps:groupby(f)\n" |
241 | " local function _aggregate(m, v)\n" |
242 | " local k = f and f(v) or nil;\n" |
243 | " local l = m[k] or list()\n" |
244 | " list.append(l, v)\n" |
245 | " m[k] = l;\n" |
246 | " return m;\n" |
247 | " end\n" |
248 | " local function _merge(l1, l2)\n" |
249 | " local l = list.clone(l1)\n" |
250 | " for v in list.iterator(l2) do\n" |
251 | " list.append(l, v)\n" |
252 | " end\n" |
253 | " return l\n" |
254 | " end\n" |
255 | " function _reduce(m1, m2)\n" |
256 | " return map.merge(m1, m2, _merge)\n" |
257 | " end\n" |
258 | " return self : aggregate(map(), _aggregate) : reduce(_reduce)\n" |
259 | "end\n" |
260 | ; |
261 | |
262 | size_t as_lua_stream_ops_size = sizeof(as_lua_stream_ops); |
263 | |
264 | const char as_lua_aerospike[] = |
265 | "sandboxed = {}\n" |
266 | "ldebug = debug;\n" |
267 | "function trace(m, ...)\n" |
268 | " return aerospike:log(4, string.format(m, ...))\n" |
269 | "end\n" |
270 | "function debug(m, ...)\n" |
271 | " return aerospike:log(3, string.format(m, ...))\n" |
272 | "end\n" |
273 | "function info(m, ...)\n" |
274 | " return aerospike:log(2, string.format(m, ...))\n" |
275 | "end\n" |
276 | "function warn(m, ...)\n" |
277 | " return aerospike:log(1, string.format(m, ...))\n" |
278 | "end\n" |
279 | "function env_record()\n" |
280 | " return {\n" |
281 | " [\"record\"] = record,\n" |
282 | " [\"iterator\"] = iterator,\n" |
283 | " [\"list\"] = list,\n" |
284 | " [\"map\"] = map,\n" |
285 | " [\"bytes\"] = bytes,\n" |
286 | " [\"geojson\"] = geojson,\n" |
287 | " [\"aerospike\"] = aerospike,\n" |
288 | " [\"Map\"] = Map, \n" |
289 | " [\"List\"] = List,\n" |
290 | " [\"Bytes\"] = Bytes,\n" |
291 | " [\"GeoJSON\"] = GeoJSON,\n" |
292 | " [\"putX\"] = putX,\n" |
293 | " [\"trace\"] = trace,\n" |
294 | " [\"debug\"] = debug,\n" |
295 | " [\"info\"] = info,\n" |
296 | " [\"warn\"] = warn,\n" |
297 | " [\"collectgarbage\"] = collectgarbage,\n" |
298 | " [\"error\"] = error,\n" |
299 | " [\"getmetatable\"] = getmetatable,\n" |
300 | " [\"ipairs\"] = ipairs,\n" |
301 | " [\"load\"] = load,\n" |
302 | " [\"module\"] = module,\n" |
303 | " [\"next\"] = next,\n" |
304 | " [\"pairs\"] = pairs,\n" |
305 | " [\"print\"] = print,\n" |
306 | " [\"pcall\"] = pcall,\n" |
307 | " [\"rawequal\"] = rawequal,\n" |
308 | " [\"rawget\"] = rawget,\n" |
309 | " [\"rawset\"] = rawset,\n" |
310 | " [\"require\"] = require,\n" |
311 | " [\"require\"] = require,\n" |
312 | " [\"select\"] = select,\n" |
313 | " [\"setmetatable\"] = setmetatable,\n" |
314 | " [\"setfenv\"] = setfenv,\n" |
315 | " [\"tonumber\"] = tonumber,\n" |
316 | " [\"tostring\"] = tostring,\n" |
317 | " [\"type\"] = type,\n" |
318 | " [\"unpack\"] = unpack,\n" |
319 | " [\"xpcall\"] = xpcall,\n" |
320 | " [\"math\"] = math,\n" |
321 | " [\"io\"] = io,\n" |
322 | " [\"os\"] = {\n" |
323 | " ['clock'] = os.clock,\n" |
324 | " ['date'] = os.date,\n" |
325 | " ['difftime'] = os.difftime,\n" |
326 | " ['getenv'] = os.getenv,\n" |
327 | " ['setlocale'] = os.setlocale,\n" |
328 | " ['time'] = os.time,\n" |
329 | " ['tmpname'] = os.tmpname\n" |
330 | " },\n" |
331 | " [\"package\"] = package,\n" |
332 | " [\"string\"] = string,\n" |
333 | " [\"table\"] = table,\n" |
334 | " [\"_G\"] = {}\n" |
335 | " }\n" |
336 | "end\n" |
337 | "function apply_record(f, r, ...)\n" |
338 | " if f == nil then\n" |
339 | " error(\"function not found\", 2)\n" |
340 | " end\n" |
341 | " if not sandboxed[f] then\n" |
342 | " setfenv(f,env_record())\n" |
343 | " sandboxed[f] = true\n" |
344 | " end\n" |
345 | " success, result = pcall(f, r, ...)\n" |
346 | " if success then\n" |
347 | " return result\n" |
348 | " else\n" |
349 | " error(result, 2)\n" |
350 | " return nil\n" |
351 | " end\n" |
352 | "end\n" |
353 | "function apply_stream(f, scope, istream, ostream, ...)\n" |
354 | " if f == nil then\n" |
355 | " error(\"function not found\", 2)\n" |
356 | " return 2\n" |
357 | " end\n" |
358 | " if not sandboxed[f] then\n" |
359 | " setfenv(f,env_record())\n" |
360 | " sandboxed[f] = true\n" |
361 | " end\n" |
362 | " local stream_ops = StreamOps_create();\n" |
363 | " success, result = pcall(f, stream_ops, ...)\n" |
364 | " if success then\n" |
365 | " local ops = StreamOps_select(result.ops, scope);\n" |
366 | " local values = StreamOps_apply(stream_iterator(istream), ops);\n" |
367 | " for value in values do\n" |
368 | " if stream.write(ostream, value) ~= 0 then\n" |
369 | " break\n" |
370 | " end\n" |
371 | " end\n" |
372 | " stream.write(ostream, nil)\n" |
373 | " return 0\n" |
374 | " else\n" |
375 | " error(result, 2)\n" |
376 | " return 2\n" |
377 | " end\n" |
378 | "end\n" |
379 | ; |
380 | |
381 | size_t as_lua_aerospike_size = sizeof(as_lua_aerospike); |
382 | |