Merge lp:~mohyt/drizzle/json_server_schema into lp:drizzle

Proposed by Mohit Srivastava on 2013-07-28
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
Reviewer Review Type Date Requested Status
Stewart Smith (community) 2013-07-28 Approve on 2013-08-13
Review via email: mp+177285@code.launchpad.net

Description of the change

Added create & drop Schema functionality on json server

To post a comment you must log in.
Stewart Smith (stewart) wrote :

Minor fixes:
- Copyright date should be 2011-2013 rather than just 2011
- It would be good to have a comment in plugin/json_server/ddl/schema.cc that it's mostly just a copy from drizzled/statement/create_schema.cc and friends.
- 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.

review: Needs Fixing
lp:~mohyt/drizzle/json_server_schema updated on 2013-08-13
2639. By Mohit Srivastava on 2013-08-13

Changes related to Review.

Mohit Srivastava (mohyt) wrote :

Changes done. Ready to merge.
No change related to buffer overflow as it already handle by libevent.

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'

Subscribers

People subscribed via source and target branches