Merge lp:~mohyt/drizzle/json_server_schema into lp:drizzle
- json_server_schema
- Merge into 7.2
Proposed by
Mohit Srivastava
Status: | Merged |
---|---|
Merged at revision: | 2642 |
Proposed branch: | lp:~mohyt/drizzle/json_server_schema |
Merge into: | lp:drizzle |
Diff against target: |
1049 lines (+935/-2) 10 files modified
plugin/json_server/ddl/schema.cc (+158/-0) plugin/json_server/ddl/schema.h (+110/-0) plugin/json_server/error.cc (+58/-0) plugin/json_server/error.h (+158/-0) plugin/json_server/json_handler.cc (+101/-0) plugin/json_server/json_handler.h (+125/-0) plugin/json_server/json_server.cc (+107/-2) plugin/json_server/plugin.ini (+6/-0) plugin/json_server/tests/r/basic.result (+18/-0) plugin/json_server/tests/t/basic.test (+94/-0) |
To merge this branch: | bzr merge lp:~mohyt/drizzle/json_server_schema |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stewart Smith (community) | Approve | ||
Review via email: mp+177285@code.launchpad.net |
Commit message
Description of the change
Added create & drop Schema functionality on json server
To post a comment you must log in.
- 2639. By Mohit Srivastava
-
Changes related to Review.
Revision history for this message
Mohit Srivastava (mohyt) wrote : | # |
Changes done. Ready to merge.
No change related to buffer overflow as it already handle by libevent.
Revision history for this message
Stewart Smith (stewart) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory 'plugin/json_server/ddl' |
2 | === added file 'plugin/json_server/ddl/schema.cc' |
3 | --- plugin/json_server/ddl/schema.cc 1970-01-01 00:00:00 +0000 |
4 | +++ plugin/json_server/ddl/schema.cc 2013-08-13 04:20:40 +0000 |
5 | @@ -0,0 +1,158 @@ |
6 | +/* mode: c; c-basic-offset: 2; indent-tabs-mode: nil; |
7 | + * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
8 | + * |
9 | + * Copyright (C) 2011-2013 Stewart Smith, Henrik Ingo, Mohit Srivastava |
10 | + * |
11 | + * This program is free software; you can redistribute it and/or modify |
12 | + * it under the terms of the GNU General Public License as published by |
13 | + * the Free Software Foundation; either version 2 of the License, or |
14 | + * (at your option) any later version. |
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 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 02110-1301 USA |
24 | + */ |
25 | +/** |
26 | + * @file Implements a class Schema to handle various operations related to schema.Its just a copy of drizzled/schema.cc and its friends. |
27 | + */ |
28 | + |
29 | + #include <config.h> |
30 | + |
31 | + #include <drizzled/show.h> |
32 | + #include <drizzled/session.h> |
33 | + #include <drizzled/schema.h> |
34 | + #include <drizzled/message.h> |
35 | + #include <drizzled/sql_lex.h> |
36 | + #include <drizzled/plugin/event_observer.h> |
37 | + #include <drizzled/catalog/instance.h> |
38 | + #include <plugin/json_server/ddl/schema.h> |
39 | + #include <drizzled/plugin/authorization.h> |
40 | + #include <drizzled/plugin/storage_engine.h> |
41 | + |
42 | + #include <string> |
43 | + |
44 | + |
45 | + using namespace std; |
46 | + using namespace drizzled; |
47 | + |
48 | + namespace drizzle_plugin { |
49 | + namespace json_server { |
50 | + |
51 | + bool Schema::createSchema() |
52 | + { |
53 | + if (not validateSchemaOptions()) |
54 | + return true; |
55 | + |
56 | + if (session().inTransaction()) |
57 | + { |
58 | + my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0)); |
59 | + return true; |
60 | + } |
61 | + |
62 | + drizzled::identifier::Schema schema_identifier(session().catalog().identifier(),_db_name); |
63 | + |
64 | + if (not check(schema_identifier)) |
65 | + return false; |
66 | + |
67 | + drizzled::message::schema::init(schema_message, schema_identifier); |
68 | + message::set_definer(schema_message, *session().user()); |
69 | + |
70 | + bool res =false; |
71 | + std::string path = schema_identifier.getSQLPath(); |
72 | + |
73 | + if (unlikely(plugin::EventObserver::beforeCreateDatabase(session(), path))) |
74 | + { |
75 | + my_error(ER_EVENT_OBSERVER_PLUGIN, MYF(0), path.c_str()); |
76 | + } |
77 | + else |
78 | + { |
79 | + res= schema::create(session(), schema_message, false); |
80 | + if (unlikely(plugin::EventObserver::afterCreateDatabase(session(), path, res))) |
81 | + { |
82 | + my_error(ER_EVENT_OBSERVER_PLUGIN, schema_identifier); |
83 | + res = false; |
84 | + } |
85 | + } |
86 | + return not res; |
87 | + } |
88 | + |
89 | + bool Schema::dropSchema() |
90 | + { |
91 | + if (session().inTransaction()) |
92 | + { |
93 | + my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0)); |
94 | + return true; |
95 | + } |
96 | + |
97 | + drizzled::identifier::Schema schema_identifier(session().catalog().identifier(),_db_name); |
98 | + |
99 | + if (not schema::check(session(),schema_identifier)) |
100 | + { |
101 | + my_error(ER_WRONG_DB_NAME, schema_identifier); |
102 | + return false; |
103 | + } |
104 | + |
105 | + if (session().inTransaction()) |
106 | + { |
107 | + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); |
108 | + return true; |
109 | + } |
110 | + |
111 | + bool res = true; |
112 | + std::string path = schema_identifier.getSQLPath(); |
113 | + if (unlikely(plugin::EventObserver::beforeDropDatabase(session(), path))) |
114 | + { |
115 | + my_error(ER_EVENT_OBSERVER_PLUGIN, schema_identifier); |
116 | + } |
117 | + else |
118 | + { |
119 | + res= schema::drop(session(), schema_identifier, false); |
120 | + if (unlikely(plugin::EventObserver::afterDropDatabase(session(), path, res))) |
121 | + { |
122 | + my_error(ER_EVENT_OBSERVER_PLUGIN, MYF(0), path.c_str()); |
123 | + res = false; |
124 | + } |
125 | + } |
126 | + |
127 | + return res; |
128 | + |
129 | + } |
130 | + |
131 | + bool Schema::validateSchemaOptions() |
132 | + { |
133 | + size_t num_engine_options= schema_message.engine().options_size(); |
134 | + bool rc= num_engine_options ? false : true; |
135 | + |
136 | + for (size_t y= 0; y < num_engine_options; ++y) |
137 | + { |
138 | + my_error(ER_UNKNOWN_SCHEMA_OPTION, MYF(0),schema_message.engine().options(y).name().c_str(),schema_message.engine().options(y).state().c_str()); |
139 | + rc= false; |
140 | + } |
141 | + return rc; |
142 | + |
143 | + } |
144 | + |
145 | + bool Schema::check(const identifier::Schema &identifier) |
146 | + { |
147 | + if (not identifier.isValid()) |
148 | + return false; |
149 | + |
150 | + if (not plugin::Authorization::isAuthorized(*session().user(), identifier)) |
151 | + return false; |
152 | + |
153 | + if (plugin::StorageEngine::doesSchemaExist(identifier)) |
154 | + { |
155 | + my_error(ER_DB_CREATE_EXISTS, identifier); |
156 | + return false; |
157 | + } |
158 | + |
159 | + return true; |
160 | + } |
161 | +} |
162 | +} |
163 | + |
164 | |
165 | === added file 'plugin/json_server/ddl/schema.h' |
166 | --- plugin/json_server/ddl/schema.h 1970-01-01 00:00:00 +0000 |
167 | +++ plugin/json_server/ddl/schema.h 2013-08-13 04:20:40 +0000 |
168 | @@ -0,0 +1,110 @@ |
169 | +/** - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
170 | + * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
171 | + * |
172 | + * Copyright (C) 2011-2013 Stewart Smith, Henrik Ingo, Mohit Srivastava |
173 | + * |
174 | + * This program is free software; you can redistribute it and/or modify |
175 | + * it under the terms of the GNU General Public License as published by |
176 | + * the Free Software Foundation; either version 2 of the License, or |
177 | + * (at your option) any later version. |
178 | + * |
179 | + * This program is distributed in the hope that it will be useful, |
180 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
181 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
182 | + * GNU General Public License for more details. |
183 | + * |
184 | + * You should have received a copy of the GNU General Public License |
185 | + * along with this program; if not, write to the Free Software |
186 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
187 | + */ |
188 | +/** |
189 | + * @file Declare a class Schema to perform various operations related to schema. |
190 | + */ |
191 | +#include <drizzled/session.h> |
192 | +#include <drizzled/statement.h> |
193 | +#include <drizzled/message/schema.pb.h> |
194 | +#include <uuid/uuid.h> |
195 | +#include <drizzled/definitions.h> |
196 | +#include <drizzled/error.h> |
197 | +#include <drizzled/sql_parse.h> |
198 | +#include <drizzled/sql_base.h> |
199 | +#include <string> |
200 | +using namespace std; |
201 | +using namespace drizzled; |
202 | +namespace drizzle_plugin { |
203 | +namespace json_server { |
204 | + /** |
205 | + * a class. |
206 | + * |
207 | + * To perform various operations related to schema. |
208 | + */ |
209 | + class Schema |
210 | + { |
211 | + public: |
212 | + /** |
213 | + * Constructor. |
214 | + * |
215 | + * @param in_session a session object. |
216 | + * @param db_name a schema name string. |
217 | + */ |
218 | + Schema(Session *in_session,string db_name) : |
219 | + _session(*in_session),_db_name(db_name) |
220 | + {} |
221 | + /** |
222 | + * Stores whether schema exist or not. |
223 | + */ |
224 | + bool is_if_not_exists; |
225 | + /** |
226 | + * Stores schema message. |
227 | + */ |
228 | + message::Schema schema_message; |
229 | + /** |
230 | + * create a new schema if it not exists. |
231 | + * |
232 | + * @return false Success. |
233 | + * @return true Failure. |
234 | + */ |
235 | + bool createSchema(); |
236 | + /** |
237 | + * drop a schema if it exists. |
238 | + * |
239 | + * @return false Success. |
240 | + * @reutrn true Failure. |
241 | + */ |
242 | + bool dropSchema(); |
243 | + /** |
244 | + * Get a session object. |
245 | + * |
246 | + * @return a session object. |
247 | + */ |
248 | + Session& session() const{ |
249 | + return _session; |
250 | + } |
251 | + |
252 | + private: |
253 | + /** |
254 | + * Validates various schema options. |
255 | + * |
256 | + * @return false Success. |
257 | + * @return true Failure. |
258 | + */ |
259 | + bool validateSchemaOptions(); |
260 | + /** |
261 | + * Checks whether schema exists or not already. |
262 | + * |
263 | + * @return false Success. |
264 | + * @return true Failure. |
265 | + */ |
266 | + bool check(const identifier::Schema &identifier); |
267 | + /** |
268 | + * Stores a session object. |
269 | + */ |
270 | + Session& _session; |
271 | + /** |
272 | + * Stores a schema name. |
273 | + */ |
274 | + string _db_name; |
275 | + }; |
276 | + |
277 | +} |
278 | +} |
279 | |
280 | === added file 'plugin/json_server/error.cc' |
281 | --- plugin/json_server/error.cc 1970-01-01 00:00:00 +0000 |
282 | +++ plugin/json_server/error.cc 2013-08-13 04:20:40 +0000 |
283 | @@ -0,0 +1,58 @@ |
284 | + /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
285 | + * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
286 | + * |
287 | + * Copyright (C) 2011-2013 Stewart Smith, Henrik Ingo, Mohit Srivastava |
288 | + * |
289 | + * This program is free software; you can redistribute it and/or modify |
290 | + * it under the terms of the GNU General Public License as published by |
291 | + * the Free Software Foundation; either version 2 of the License, or |
292 | + * (at your option) any later version. |
293 | + * |
294 | + * This program is distributed in the hope that it will be useful, |
295 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
296 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
297 | + * GNU General Public License for more details. |
298 | + * |
299 | + * You should have received a copy of the GNU General Public License |
300 | + * along with this program; if not, write to the Free Software |
301 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
302 | + */ |
303 | +/** |
304 | + * @file Implements JsonErrorArea class which handles errors of json server. |
305 | + */ |
306 | +#include <plugin/json_server/error.h> |
307 | +#include <drizzled/error/sql_state.h> |
308 | + |
309 | +namespace drizzle_plugin |
310 | +{ |
311 | +namespace json_server |
312 | +{ |
313 | + JsonErrorArea::JsonErrorArea() |
314 | + { |
315 | + reset_jsonerror_area(); |
316 | + } |
317 | + |
318 | + void JsonErrorArea::reset_jsonerror_area() |
319 | + { |
320 | + er_type = ER_EMPTY; |
321 | + error_no = drizzled::EE_OK; |
322 | + error_msg= ""; |
323 | + sql_state="00000"; |
324 | + } |
325 | + |
326 | + void JsonErrorArea::set_error(enum_error_type error_type_arg,drizzled::error_t error_no_arg,const char * error_msg_arg) |
327 | + { |
328 | + if(error_type_arg != ER_EMPTY) |
329 | + { |
330 | + er_type = error_type_arg; |
331 | + error_msg = error_msg_arg; |
332 | + |
333 | + if(error_type_arg == ER_SQL) |
334 | + { |
335 | + error_no = error_no_arg; |
336 | + sql_state = drizzled::error::convert_to_sqlstate(error_no_arg); |
337 | + } |
338 | + } |
339 | + } |
340 | +} |
341 | +} |
342 | |
343 | === added file 'plugin/json_server/error.h' |
344 | --- plugin/json_server/error.h 1970-01-01 00:00:00 +0000 |
345 | +++ plugin/json_server/error.h 2013-08-13 04:20:40 +0000 |
346 | @@ -0,0 +1,158 @@ |
347 | + /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
348 | + * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
349 | + * |
350 | + * Copyright (C) 2011-2013 Stewart Smith, Henrik Ingo, Mohit Srivastava |
351 | + * |
352 | + * This program is free software; you can redistribute it and/or modify |
353 | + * it under the terms of the GNU General Public License as published by |
354 | + * the Free Software Foundation; either version 2 of the License, or |
355 | + * (at your option) any later version. |
356 | + * |
357 | + * This program is distributed in the hope that it will be useful, |
358 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
359 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
360 | + * GNU General Public License for more details. |
361 | + * |
362 | + * You should have received a copy of the GNU General Public License |
363 | + * along with this program; if not, write to the Free Software |
364 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
365 | + */ |
366 | +/** |
367 | + * @file Declare a class to handle errors in json server. |
368 | + */ |
369 | +#include <config.h> |
370 | + |
371 | +#include <drizzled/error_t.h> |
372 | +#include <string> |
373 | +namespace drizzle_plugin |
374 | +{ |
375 | +namespace json_server |
376 | +{ |
377 | + /** |
378 | + * a class |
379 | + * used to handle various errors of json server. |
380 | + */ |
381 | + class JsonErrorArea |
382 | + { |
383 | + public: |
384 | + /** |
385 | + * an enumerated data type for different type of error in json server. |
386 | + */ |
387 | + enum enum_error_type |
388 | + { |
389 | + ER_EMPTY=0, |
390 | + ER_SQL, |
391 | + ER_JSON, |
392 | + ER_HTTP, |
393 | + ER_UNKNOWN |
394 | + }; |
395 | + /** |
396 | + * Constructor. |
397 | + */ |
398 | + JsonErrorArea(); |
399 | + /** |
400 | + * Reset the memeber values. |
401 | + */ |
402 | + void reset_jsonerror_area(); |
403 | + /** |
404 | + * Set an error with details. |
405 | + */ |
406 | + void set_error(enum_error_type type,drizzled::error_t sql_errno_arg,const char *message_arg); |
407 | + /** |
408 | + * Check whether error or not. |
409 | + * |
410 | + * @return true Success. |
411 | + * @return false Failure. |
412 | + */ |
413 | + bool is_error(){return er_type!= ER_EMPTY;} |
414 | + /** |
415 | + * Check whether sql error or not. |
416 | + * |
417 | + * @return true Success. |
418 | + * @return false Failure. |
419 | + */ |
420 | + bool is_sqlerror(){return er_type == ER_SQL;} |
421 | + /** |
422 | + * Check whether json error or not. |
423 | + * |
424 | + * @return true Success. |
425 | + * @return false Failure. |
426 | + */ |
427 | + bool is_jsonerror(){return er_type == ER_JSON;} |
428 | + /** |
429 | + * Check whether http error or not. |
430 | + * |
431 | + * @return true Success. |
432 | + * @return false Failure. |
433 | + */ |
434 | + bool is_httperror(){return er_type == ER_HTTP;} |
435 | + /** |
436 | + * Check whether unknown error or not. |
437 | + * |
438 | + * @return true Success. |
439 | + * @return false Failure. |
440 | + */ |
441 | + bool is_unknownerror(){return er_type == ER_UNKNOWN;} |
442 | + /** |
443 | + * Get an error number. |
444 | + * |
445 | + * @return a error number. |
446 | + */ |
447 | + drizzled::error_t get_error_no() const { return error_no;} |
448 | + /** |
449 | + * Get an error message. |
450 | + * |
451 | + * @return a const error message string. |
452 | + */ |
453 | + const char* get_error_msg() const { return error_msg;} |
454 | + /** |
455 | + * Get sql state. |
456 | + * |
457 | + * @return a const sql state string. |
458 | + */ |
459 | + const char* get_sql_state() const { return sql_state;} |
460 | + /** |
461 | + * Get error type. |
462 | + * |
463 | + * @return a error type. |
464 | + */ |
465 | + enum_error_type get_error_type() const { return er_type;} |
466 | + /** |
467 | + * Get error type string. |
468 | + * |
469 | + * @return a error type string. |
470 | + */ |
471 | + std::string get_error_type_string() const { |
472 | + std::string error_str; |
473 | + switch(er_type) |
474 | + { |
475 | + case ER_EMPTY: {error_str="NO ERROR"; break;} |
476 | + case ER_SQL: {error_str="SQL ERROR"; break;} |
477 | + case ER_JSON: {error_str="JSON ERROR"; break;} |
478 | + case ER_HTTP: {error_str="HTTP ERROR"; break;} |
479 | + case ER_UNKNOWN: {error_str="UNKNOWN ERROR"; break;} |
480 | + } |
481 | + return error_str; |
482 | + } |
483 | + |
484 | + private: |
485 | + /** |
486 | + * Stores error type. |
487 | + */ |
488 | + enum_error_type er_type; |
489 | + /** |
490 | + * Stores error number. |
491 | + */ |
492 | + drizzled::error_t error_no; |
493 | + /** |
494 | + * Stores error message. |
495 | + */ |
496 | + const char *error_msg; |
497 | + /** |
498 | + * Stores sql state. |
499 | + */ |
500 | + const char *sql_state; |
501 | + |
502 | + }; |
503 | +} |
504 | +} |
505 | |
506 | === added file 'plugin/json_server/json_handler.cc' |
507 | --- plugin/json_server/json_handler.cc 1970-01-01 00:00:00 +0000 |
508 | +++ plugin/json_server/json_handler.cc 2013-08-13 04:20:40 +0000 |
509 | @@ -0,0 +1,101 @@ |
510 | + /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
511 | + * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
512 | + * |
513 | + * Copyright (C) 2011-2013 Stewart Smith, Henrik Ingo, Mohit Srivastava |
514 | + * |
515 | + * This program is free software; you can redistribute it and/or modify |
516 | + * it under the terms of the GNU General Public License as published by |
517 | + * the Free Software Foundation; either version 2 of the License, or |
518 | + * (at your option) any later version. |
519 | + * |
520 | + * This program is distributed in the hope that it will be useful, |
521 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
522 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
523 | + * GNU General Public License for more details. |
524 | + * |
525 | + * You should have received a copy of the GNU General Public License |
526 | + * along with this program; if not, write to the Free Software |
527 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
528 | + */ |
529 | +/* |
530 | + * @file Implements a class JsonHandler which handles the operations related to Json. |
531 | + */ |
532 | +#include <plugin/json_server/json_handler.h> |
533 | +#include <string.h> |
534 | +using namespace drizzled; |
535 | +namespace drizzle_plugin |
536 | +{ |
537 | +namespace json_server |
538 | +{ |
539 | + void JsonHandler::generate_input_query(struct evhttp_request *req_arg) |
540 | + { |
541 | + evhttp_parse_query(evhttp_request_uri(req_arg), req_arg->input_headers); |
542 | + if(req_arg->type== EVHTTP_REQ_POST ) |
543 | + { |
544 | + char buffer[1024]; |
545 | + int l=0; |
546 | + do |
547 | + { |
548 | + l= evbuffer_remove(req_arg->input_buffer, buffer, 1024); |
549 | + _input_query.append(buffer, l); |
550 | + } |
551 | + while(l); |
552 | + } |
553 | + else |
554 | + { |
555 | + const char* _query; |
556 | + _query= (char *)evhttp_find_header(req_arg->input_headers, "query"); |
557 | + if(_query == NULL || strcmp(_query,"")==0) |
558 | + { |
559 | + _query="{}"; |
560 | + } |
561 | + _input_query.append(_query,strlen(_query)); |
562 | + } |
563 | + |
564 | + } |
565 | + |
566 | + void JsonHandler::generate_input_json(struct evhttp_request *req_arg,JsonErrorArea &_json_error_area) |
567 | + { |
568 | + generate_input_query(req_arg); |
569 | + Json::Features _json_conf; |
570 | + Json::Reader reader(_json_conf); |
571 | + bool retval = reader.parse(_input_query,_json_in); |
572 | + if(retval!=true) |
573 | + { |
574 | + _json_error_area.set_error(JsonErrorArea::ER_JSON,drizzled::EE_OK,reader.getFormatedErrorMessages().c_str()); |
575 | + } |
576 | + } |
577 | + |
578 | + void JsonHandler::generate_output_json(JsonErrorArea& _json_error_area) |
579 | + { |
580 | + if(_json_error_area.is_error()) |
581 | + { |
582 | + if(_json_error_area.is_sqlerror()) |
583 | + { |
584 | + _json_out["error_type"]=_json_error_area.get_error_type_string(); |
585 | + _json_out["error_no"]=_json_error_area.get_error_no(); |
586 | + _json_out["error_message"]=_json_error_area.get_error_msg(); |
587 | + _json_out["sql_state"]=_json_error_area.get_sql_state(); |
588 | + |
589 | + } |
590 | + else |
591 | + { |
592 | + _json_out["error_type"]=_json_error_area.get_error_type_string(); |
593 | + _json_out["error_message"]=_json_error_area.get_error_msg(); |
594 | + } |
595 | + } |
596 | + else |
597 | + { |
598 | + _json_out["sql_state"]=_json_error_area.get_sql_state(); |
599 | + } |
600 | + |
601 | + } |
602 | + |
603 | + void JsonHandler::generate_output_query(JsonErrorArea& _json_error_area) |
604 | + { |
605 | + generate_output_json(_json_error_area); |
606 | + Json::StyledWriter writer; |
607 | + _output_query= writer.write(_json_out); |
608 | + } |
609 | +} |
610 | +} |
611 | |
612 | === added file 'plugin/json_server/json_handler.h' |
613 | --- plugin/json_server/json_handler.h 1970-01-01 00:00:00 +0000 |
614 | +++ plugin/json_server/json_handler.h 2013-08-13 04:20:40 +0000 |
615 | @@ -0,0 +1,125 @@ |
616 | + /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
617 | + * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
618 | + * |
619 | + * Copyright (C) 2011-2013 Stewart Smith, Henrik Ingo, Mohit Srivastava |
620 | + * |
621 | + * This program is free software; you can redistribute it and/or modify |
622 | + * it under the terms of the GNU General Public License as published by |
623 | + * the Free Software Foundation; either version 2 of the License, or |
624 | + * (at your option) any later version. |
625 | + * |
626 | + * This program is distributed in the hope that it will be useful, |
627 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
628 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
629 | + * GNU General Public License for more details. |
630 | + * |
631 | + * You should have received a copy of the GNU General Public License |
632 | + * along with this program; if not, write to the Free Software |
633 | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
634 | + */ |
635 | +/** |
636 | + * @file Declare a class JsonHandler which handles the operations related to Json. |
637 | + **/ |
638 | + |
639 | +#include <config.h> |
640 | + |
641 | +#include <plugin/json_server/json/json.h> |
642 | +#include <evhttp.h> |
643 | +#include <event.h> |
644 | +#include <drizzled/session.h> |
645 | +#include <plugin/json_server/error.h> |
646 | + |
647 | +using namespace drizzled; |
648 | +namespace drizzle_plugin |
649 | +{ |
650 | +namespace json_server |
651 | +{ |
652 | + /* |
653 | + * a class. |
654 | + * used to handle operations related to Json. |
655 | + */ |
656 | + class JsonHandler |
657 | + { |
658 | + public: |
659 | + /* |
660 | + * Generate an input query from http request object. |
661 | + * |
662 | + * @param req_arg the http request object. |
663 | + */ |
664 | + void generate_input_query(struct evhttp_request *req_arg); |
665 | + /* |
666 | + * Generate an input json from http request object. |
667 | + * |
668 | + * @param req_arg the http request object. |
669 | + * @param _json_error_area the JsonErrorArea object to handle error. |
670 | + */ |
671 | + void generate_input_json(struct evhttp_request *req_arg,JsonErrorArea &_json_error_area); |
672 | + /* |
673 | + * Generate an output query string. |
674 | + * |
675 | + * @param _json_error_area the JsonErrorArea object to handle error. |
676 | + */ |
677 | + void generate_output_query(JsonErrorArea& _json_error_area); |
678 | + /* |
679 | + * Generate an output Json. |
680 | + * |
681 | + * @param _json_error_area the JsonErrorArea object to handle error. |
682 | + */ |
683 | + void generate_output_json(JsonErrorArea& _json_error_area); |
684 | + /* |
685 | + * Get an output query string. |
686 | + * |
687 | + * @return a const output query string. |
688 | + */ |
689 | + const std::string& get_output_query() const |
690 | + { |
691 | + return _output_query; |
692 | + } |
693 | + /* |
694 | + * Get an input query string. |
695 | + * |
696 | + * @return a const input query string. |
697 | + */ |
698 | + const std::string& get_input_query() const |
699 | + { |
700 | + return _input_query; |
701 | + } |
702 | + /* |
703 | + * Get an output json object. |
704 | + * |
705 | + * @return a const json object. |
706 | + */ |
707 | + const Json::Value get_output_json() const |
708 | + { |
709 | + return _json_out; |
710 | + } |
711 | + /* |
712 | + * Get an input json object. |
713 | + * |
714 | + * @return a const json object. |
715 | + */ |
716 | + const Json::Value get_input_json() const |
717 | + { |
718 | + return _json_in; |
719 | + } |
720 | + |
721 | + private: |
722 | + /* |
723 | + * Stores input json object. |
724 | + */ |
725 | + Json::Value _json_in; |
726 | + /* |
727 | + * Stores output json object. |
728 | + */ |
729 | + Json::Value _json_out; |
730 | + /* |
731 | + * Stores input string. |
732 | + */ |
733 | + std::string _input_query; |
734 | + /* |
735 | + * Stores output string. |
736 | + */ |
737 | + std::string _output_query; |
738 | + }; |
739 | +} |
740 | +} |
741 | |
742 | === modified file 'plugin/json_server/json_server.cc' |
743 | --- plugin/json_server/json_server.cc 2012-07-17 09:30:57 +0000 |
744 | +++ plugin/json_server/json_server.cc 2013-08-13 04:20:40 +0000 |
745 | @@ -1,7 +1,7 @@ |
746 | /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
747 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
748 | * |
749 | - * Copyright (C) 2011 Stewart Smith, Henrik Ingo, Mohit Srivastava |
750 | + * Copyright (C) 2011-2013 Stewart Smith, Henrik Ingo, Mohit Srivastava |
751 | * |
752 | * This program is free software; you can redistribute it and/or modify |
753 | * it under the terms of the GNU General Public License as published by |
754 | @@ -46,10 +46,11 @@ |
755 | #include <event.h> |
756 | #include <drizzled/execute.h> |
757 | #include <drizzled/sql/result_set.h> |
758 | - |
759 | +#include <drizzled/diagnostics_area.h> |
760 | #include <drizzled/plugin/listen.h> |
761 | #include <drizzled/plugin/client.h> |
762 | #include <drizzled/catalog/local.h> |
763 | +#include <drizzled/current_session.h> |
764 | |
765 | #include <drizzled/pthread_globals.h> |
766 | #include <boost/bind.hpp> |
767 | @@ -60,6 +61,8 @@ |
768 | #include <plugin/json_server/db_access.h> |
769 | #include <plugin/json_server/http_handler.h> |
770 | #include <plugin/json_server/http_server.h> |
771 | +#include <plugin/json_server/ddl/schema.h> |
772 | +#include <plugin/json_server/json_handler.h> |
773 | |
774 | namespace po= boost::program_options; |
775 | using namespace drizzled; |
776 | @@ -95,6 +98,8 @@ |
777 | extern "C" void process_version_req(struct evhttp_request *req, void* ); |
778 | extern "C" void process_sql_req(struct evhttp_request *req, void* ); |
779 | extern "C" void process_json_req(struct evhttp_request *req, void* ); |
780 | +extern "C" void process_json_ddl_schema_create_req(struct evhttp_request *req, void* ); |
781 | +extern "C" void process_json_ddl_schema_drop_req(struct evhttp_request *req, void* ); |
782 | extern "C" void process_request(struct evhttp_request *req, void* ) |
783 | { |
784 | struct evbuffer *buf = evbuffer_new(); |
785 | @@ -357,6 +362,104 @@ |
786 | delete(handler); |
787 | } |
788 | |
789 | +/** |
790 | + * Transform a HTTP Request for create schema and returns results based on the input json. |
791 | + * |
792 | + * @param req a HTTP request parameter, |
793 | + * |
794 | + */ |
795 | + |
796 | +extern "C" void process_json_ddl_schema_create_req(struct evhttp_request *req, void* ) |
797 | +{ |
798 | + drizzled::Session::shared_ptr _session= drizzled::Session::make_shared(drizzled::plugin::Listen::getNullClient(), |
799 | + drizzled::catalog::local()); |
800 | + drizzled::identifier::user::mptr user_id= identifier::User::make_shared(); |
801 | + _session->main_da().reset_diagnostics_area(); |
802 | + setCurrentSession(_session.get()); |
803 | + |
804 | + std::string query; |
805 | + std::string db_name; |
806 | + std::string output; |
807 | + Json::Value json_out; |
808 | + Json::Value json_in; |
809 | + const char *http_response_text="OK"; |
810 | + int http_response_code=HTTP_OK; |
811 | + |
812 | + JsonErrorArea _json_error; |
813 | + JsonHandler* _json_handler = new JsonHandler(); |
814 | + |
815 | + _json_handler->generate_input_json(req,_json_error); |
816 | + if(!_json_error.is_jsonerror()) |
817 | + { |
818 | + json_in = _json_handler->get_input_json(); |
819 | + db_name=json_in["query"]["name"].asString(); |
820 | + Schema *_schema = new Schema(_session.get(),db_name); |
821 | + _schema->createSchema(); |
822 | + if(_session->main_da().is_error()) |
823 | + { |
824 | + _json_error.set_error(JsonErrorArea::ER_SQL,_session->main_da().sql_errno(),_session->main_da().message()); |
825 | + } |
826 | + } |
827 | + _json_handler->generate_output_query(_json_error); |
828 | + output = _json_handler->get_output_query(); |
829 | + struct evbuffer *buf = evbuffer_new(); |
830 | + if(buf == NULL) |
831 | + { |
832 | + return; |
833 | + } |
834 | + evbuffer_add(buf, output.c_str(), output.length()); |
835 | + evhttp_send_reply( req, http_response_code, http_response_text, buf); |
836 | +} |
837 | + |
838 | +/** |
839 | +* Transform a HTTP Request for create schema and returns results based on the input json. |
840 | +* |
841 | +* @param req a HTTP request parameter. |
842 | +*/ |
843 | +extern "C" void process_json_ddl_schema_drop_req(struct evhttp_request *req, void* ) |
844 | +{ |
845 | + drizzled::Session::shared_ptr _session= drizzled::Session::make_shared(drizzled::plugin::Listen::getNullClient(), |
846 | + drizzled::catalog::local()); |
847 | + drizzled::identifier::user::mptr user_id= identifier::User::make_shared(); |
848 | + _session->main_da().reset_diagnostics_area(); |
849 | + setCurrentSession(_session.get()); |
850 | + |
851 | + std::string query; |
852 | + std::string db_name; |
853 | + std::string output; |
854 | + Json::Value json_out; |
855 | + Json::Value json_in; |
856 | + const char *http_response_text="OK"; |
857 | + int http_response_code=HTTP_OK; |
858 | + |
859 | + JsonErrorArea _json_error; |
860 | + JsonHandler* _json_handler = new JsonHandler(); |
861 | + |
862 | + _json_handler->generate_input_json(req,_json_error); |
863 | + if(!_json_error.is_jsonerror()) |
864 | + { |
865 | + json_in = _json_handler->get_input_json(); |
866 | + |
867 | + db_name=json_in["query"]["name"].asString(); |
868 | + Schema *_schema = new Schema(_session.get(),db_name); |
869 | + _schema->dropSchema(); |
870 | + if(_session->main_da().is_error()) |
871 | + { |
872 | + _json_error.set_error(JsonErrorArea::ER_SQL,_session->main_da().sql_errno(),_session->main_da().message()); |
873 | + } |
874 | + } |
875 | + _json_handler->generate_output_query(_json_error); |
876 | + output = _json_handler->get_output_query(); |
877 | + struct evbuffer *buf = evbuffer_new(); |
878 | + if(buf == NULL) |
879 | + { |
880 | + return; |
881 | + } |
882 | + evbuffer_add(buf, output.c_str(), output.length()); |
883 | + evhttp_send_reply( req, http_response_code, http_response_text, buf); |
884 | +} |
885 | + |
886 | + |
887 | static void shutdown_event(int fd, short, void *arg) |
888 | { |
889 | struct event_base *base= (struct event_base *)arg; |
890 | @@ -466,6 +569,8 @@ |
891 | evhttp_set_cb(httpd, "/version", process_version_req, NULL); |
892 | evhttp_set_cb(httpd, "/sql", process_sql_req, NULL); |
893 | evhttp_set_cb(httpd, "/json", process_json_req, NULL); |
894 | + evhttp_set_cb(httpd,"/json/ddl/schema/create", process_json_ddl_schema_create_req, NULL); |
895 | + evhttp_set_cb(httpd,"/json/ddl/schema/drop", process_json_ddl_schema_drop_req, NULL); |
896 | |
897 | |
898 | event_set(&wakeup_event, wakeup_fd[0], EV_READ | EV_PERSIST, shutdown_event, base); |
899 | |
900 | === modified file 'plugin/json_server/plugin.ini' |
901 | --- plugin/json_server/plugin.ini 2013-02-06 08:10:34 +0000 |
902 | +++ plugin/json_server/plugin.ini 2013-08-13 04:20:40 +0000 |
903 | @@ -5,7 +5,10 @@ |
904 | sql_to_json_generator.h |
905 | http_handler.h |
906 | http_server.h |
907 | + json_handler.h |
908 | + error.h |
909 | db_access.h |
910 | + ddl/schema.h |
911 | json/autolink.h |
912 | json/config.h |
913 | json/features.h |
914 | @@ -25,7 +28,10 @@ |
915 | sql_to_json_generator.cc |
916 | http_handler.cc |
917 | http_server.cc |
918 | + json_handler.cc |
919 | + error.cc |
920 | db_access.cc |
921 | + ddl/schema.cc |
922 | json/json_reader.cpp |
923 | json/json_value.cpp |
924 | json/json_writer.cpp |
925 | |
926 | === modified file 'plugin/json_server/tests/r/basic.result' |
927 | --- plugin/json_server/tests/r/basic.result 2012-07-14 14:10:13 +0000 |
928 | +++ plugin/json_server/tests/r/basic.result 2013-08-13 04:20:40 +0000 |
929 | @@ -287,3 +287,21 @@ |
930 | SET GLOBAL json_server_table=""; |
931 | SET GLOBAL json_server_schema="test"; |
932 | drop schema json; |
933 | +{ |
934 | + "sql_state" : "00000" |
935 | +} |
936 | +{ |
937 | + "error_message" : "Can't create schema 'json'; schema exists", |
938 | + "error_no" : 1007, |
939 | + "error_type" : "SQL ERROR", |
940 | + "sql_state" : "HY000" |
941 | +} |
942 | +{ |
943 | + "sql_state" : "00000" |
944 | +} |
945 | +{ |
946 | + "error_message" : "Can't drop schema 'json'; schema doesn't exist", |
947 | + "error_no" : 1008, |
948 | + "error_type" : "SQL ERROR", |
949 | + "sql_state" : "HY000" |
950 | +} |
951 | |
952 | === added file 'plugin/json_server/tests/t/basic.test' |
953 | --- plugin/json_server/tests/t/basic.test 1970-01-01 00:00:00 +0000 |
954 | +++ plugin/json_server/tests/t/basic.test 2013-08-13 04:20:40 +0000 |
955 | @@ -0,0 +1,94 @@ |
956 | +create table t1 (a int primary key auto_increment, b varchar(100)); |
957 | +--replace_result $JSON_SERVER_PORT PORT |
958 | +--eval select http_post("http://localhost:$JSON_SERVER_PORT/sql", 'select * from t1;'); |
959 | +insert into t1 (b) values ("from MySQL protocol"); |
960 | +--replace_result $JSON_SERVER_PORT PORT |
961 | +--eval select http_post('http://localhost:$JSON_SERVER_PORT/sql', 'select * from t1;'); |
962 | +--replace_result $JSON_SERVER_PORT PORT |
963 | +--eval select http_post('http://localhost:$JSON_SERVER_PORT/sql', 'insert into t1 (b) values (\'from http\');'); |
964 | +SELECT * from t1; |
965 | +drop table t1; |
966 | + |
967 | +create schema json; |
968 | + |
969 | +use json; |
970 | + |
971 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"_id":1,"document":{"firstname":"Henrik","lastname":"Ingo","age": 35}}}' 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
972 | + |
973 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&_id=1' |
974 | + |
975 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&query=%7B%22query%22%3A%7B%22_id%22%3A1%7D%7D' |
976 | + |
977 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"_id":1,"document":{"firstname":"Henrik","lastname":"Ingo","age": 36}}}' 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
978 | + |
979 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&_id=1' |
980 | + |
981 | +--exec curl -X POST 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&_id=2' |
982 | + |
983 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"_id":1,"document":{"firstname":"Henrik","lastname":"Ingo","age": 37}}}' 'http://localhost:$JSON_SERVER_PORT/json' |
984 | + |
985 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json' |
986 | + |
987 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"document":{"firstname":"Mohit","lastname":"Srivastava","age": 21}}}' 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
988 | + |
989 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
990 | + |
991 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&query=%7B%22query%22%3A%7B%7D%7D' |
992 | + |
993 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&query=%7B%22query%22%3A%7B%22_id%22%3A%22%22%7D%7D' |
994 | + |
995 | +SET GLOBAL json_server_schema="json"; |
996 | + |
997 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?table=people' |
998 | + |
999 | +SET GLOBAL json_server_table="people"; |
1000 | + |
1001 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json' |
1002 | + |
1003 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"_id":1 "document":{"firstname":"Henrik","lastname":"Ingo","age": 37}}}' 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
1004 | + |
1005 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"_id":1,"document":"It is for testing"}}' 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
1006 | + |
1007 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"_id":1,"document":98765}}' 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
1008 | + |
1009 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"_id":1,"document":{"firstname":"Henrik","lastname":"Ingo","age": 35},"metadata":{"interest":"opensource","nick":"hingo","dob":"16-feb-1977"}}}' 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=aboutpeople' |
1010 | + |
1011 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=aboutpeople' |
1012 | + |
1013 | +--exec curl -X DELETE 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&_id=1' |
1014 | + |
1015 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
1016 | + |
1017 | +--exec curl -X DELETE 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&query=%7B%22query%22%3A%7B%22_id%22%3A2%7D%7D' |
1018 | + |
1019 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
1020 | + |
1021 | +--exec curl -X DELETE 'http://localhost:$JSON_SERVER_PORT/json' |
1022 | + |
1023 | +--exec curl -X DELETE 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
1024 | + |
1025 | +--exec curl -X DELETE 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&query=%7B%22query%22%3A%7B%7D%7D' |
1026 | + |
1027 | +--exec curl -X DELETE 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&query=%7B%22query%22%3A%7B%22_id%22%3A%22%22%7D%7D' |
1028 | + |
1029 | +SET GLOBAL json_server_allow_drop_table="ON"; |
1030 | + |
1031 | +--exec curl -X DELETE 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people&query=%7B%22query%22%3A%7B%7D%7D' |
1032 | + |
1033 | +--exec curl 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=people' |
1034 | + |
1035 | +--exec curl -X DELETE 'http://localhost:$JSON_SERVER_PORT/json?schema=json&table=aboutpeople&query=%7B%22query%22%3A%7B%22_id%22%3A%22%22%7D%7D' |
1036 | + |
1037 | +SET GLOBAL json_server_allow_drop_table="OFF"; |
1038 | +SET GLOBAL json_server_table=""; |
1039 | +SET GLOBAL json_server_schema="test"; |
1040 | + |
1041 | +drop schema json; |
1042 | + |
1043 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"name":"json"}}' 'http://localhost:$JSON_SERVER_PORT/json/ddl/schema/create' |
1044 | + |
1045 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"name":"json"}}' 'http://localhost:$JSON_SERVER_PORT/json/ddl/schema/create' |
1046 | + |
1047 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"name":"json"}}' 'http://localhost:$JSON_SERVER_PORT/json/ddl/schema/drop' |
1048 | + |
1049 | +--exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"name":"json"}}' 'http://localhost:$JSON_SERVER_PORT/json/ddl/schema/drop' |
Minor fixes: json_server/ ddl/schema. cc that it's mostly just a copy from drizzled/ statement/ create_ schema. cc and friends.
- Copyright date should be 2011-2013 rather than just 2011
- It would be good to have a comment in plugin/
- Where you use a static buffer for processing input (buffer[1024]) please also provide i a test that tests the limits of this buffer to ensure that there are not exploitable buffer overflows.
Questions:
- Why is num_threads set to 1? I don't think this should be here.
Otherwise looks good.