Merge lp:~mohyt/drizzle/json_server_table into lp:drizzle
- json_server_table
- Merge into 7.2
Proposed by
Mohit Srivastava
Status: | Needs review |
---|---|
Proposed branch: | lp:~mohyt/drizzle/json_server_table |
Merge into: | lp:drizzle |
Diff against target: |
738 lines (+423/-49) 8 files modified
drizzled/sql_table.cc (+151/-8) drizzled/sql_table.h (+2/-0) plugin/json_server/ddl/table.cc (+64/-0) plugin/json_server/ddl/table.h (+61/-0) plugin/json_server/json_server.cc (+98/-40) plugin/json_server/plugin.ini (+3/-1) plugin/json_server/tests/r/basic.result (+27/-0) plugin/json_server/tests/t/basic.test (+17/-0) |
To merge this branch: | bzr merge lp:~mohyt/drizzle/json_server_table |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stewart Smith | Pending | ||
Review via email: mp+181014@code.launchpad.net |
Commit message
Added drop table functionality
Description of the change
To post a comment you must log in.
- 2644. By Mohit Srivastava
-
Updating Copyright year
- 2645. By Mohit Srivastava
-
Now able to drop table if exists.
Similar to:
DROP TABLE IF_EXISTS [TABLE_NAME]
Unmerged revisions
- 2645. By Mohit Srivastava
-
Now able to drop table if exists.
Similar to:
DROP TABLE IF_EXISTS [TABLE_NAME] - 2644. By Mohit Srivastava
-
Updating Copyright year
- 2643. By Mohit Srivastava
-
Adding functionality of table drop.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'drizzled/sql_table.cc' | |||
2 | --- drizzled/sql_table.cc 2013-03-03 02:44:39 +0000 | |||
3 | +++ drizzled/sql_table.cc 2013-08-22 06:28:00 +0000 | |||
4 | @@ -187,7 +187,7 @@ | |||
5 | 187 | { | 187 | { |
6 | 188 | drizzled::error_t local_error; | 188 | drizzled::error_t local_error; |
7 | 189 | 189 | ||
9 | 190 | /* Generate transaction event ONLY when we successfully drop */ | 190 | /* Generate transaction event ONLY when we successfully drop */ |
10 | 191 | if (plugin::StorageEngine::dropTable(*session, identifier, local_error)) | 191 | if (plugin::StorageEngine::dropTable(*session, identifier, local_error)) |
11 | 192 | { | 192 | { |
12 | 193 | if (message) // If we have no definition, we don't know if the table should have been replicated | 193 | if (message) // If we have no definition, we don't know if the table should have been replicated |
13 | @@ -250,6 +250,149 @@ | |||
14 | 250 | return error; | 250 | return error; |
15 | 251 | } | 251 | } |
16 | 252 | 252 | ||
17 | 253 | /** | ||
18 | 254 | * Overloaded function of rm_table_part2(). | ||
19 | 255 | * It takes table identifiers as parameter. | ||
20 | 256 | * @todo: Handle case for locked table. | ||
21 | 257 | */ | ||
22 | 258 | int rm_table_part2(Session *session, std::vector<identifier::Table> tables_identifiers, bool if_exists, | ||
23 | 259 | bool drop_temporary) | ||
24 | 260 | { | ||
25 | 261 | std::vector<identifier::Table>::iterator table; | ||
26 | 262 | util::string::vector wrong_tables; | ||
27 | 263 | int error= 0; | ||
28 | 264 | bool foreign_key_error= false; | ||
29 | 265 | |||
30 | 266 | do | ||
31 | 267 | { | ||
32 | 268 | //boost::mutex::scoped_lock scopedLock(table::Cache::mutex()); | ||
33 | 269 | |||
34 | 270 | /*if (not drop_temporary && session->lock_table_names_exclusively(tables)) | ||
35 | 271 | { | ||
36 | 272 | return 1; | ||
37 | 273 | }*/ | ||
38 | 274 | |||
39 | 275 | /* Don't give warnings for not found errors, as we already generate notes */ | ||
40 | 276 | session->no_warnings_for_error= 1; | ||
41 | 277 | |||
42 | 278 | for (table= tables_identifiers.begin(); table!=tables_identifiers.end(); ++table) | ||
43 | 279 | { | ||
44 | 280 | |||
45 | 281 | error= session->open_tables.drop_temporary_table(*table); | ||
46 | 282 | |||
47 | 283 | switch (error) { | ||
48 | 284 | case 0: | ||
49 | 285 | // removed temporary table | ||
50 | 286 | continue; | ||
51 | 287 | case -1: | ||
52 | 288 | error= 1; | ||
53 | 289 | break; | ||
54 | 290 | default: | ||
55 | 291 | // temporary table not found | ||
56 | 292 | error= 0; | ||
57 | 293 | } | ||
58 | 294 | |||
59 | 295 | if (drop_temporary == false) | ||
60 | 296 | { | ||
61 | 297 | abort_locked_tables(session, *table); | ||
62 | 298 | table::Cache::removeTable(*session, *table, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG); | ||
63 | 299 | /* | ||
64 | 300 | If the table was used in lock tables, remember it so that | ||
65 | 301 | unlock_table_names can free it | ||
66 | 302 | */ | ||
67 | 303 | drop_locked_tables(session, *table); | ||
68 | 304 | |||
69 | 305 | if (session->getKilled()) | ||
70 | 306 | { | ||
71 | 307 | error= -1; | ||
72 | 308 | break; | ||
73 | 309 | } | ||
74 | 310 | } | ||
75 | 311 | |||
76 | 312 | message::table::shared_ptr message= plugin::StorageEngine::getTableMessage(*session, *table, true); | ||
77 | 313 | |||
78 | 314 | if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, *table)) | ||
79 | 315 | { | ||
80 | 316 | // Table was not found on disk and table can't be created from engine | ||
81 | 317 | if (if_exists) | ||
82 | 318 | { | ||
83 | 319 | push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE, | ||
84 | 320 | ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), | ||
85 | 321 | table->getTableName().c_str()); | ||
86 | 322 | } | ||
87 | 323 | else | ||
88 | 324 | { | ||
89 | 325 | error= 1; | ||
90 | 326 | } | ||
91 | 327 | } | ||
92 | 328 | else | ||
93 | 329 | { | ||
94 | 330 | drizzled::error_t local_error; | ||
95 | 331 | |||
96 | 332 | /* Generate transaction event ONLY when we successfully drop */ | ||
97 | 333 | if (plugin::StorageEngine::dropTable(*session, *table, local_error)) | ||
98 | 334 | { | ||
99 | 335 | if (message) // If we have no definition, we don't know if the table should have been replicated | ||
100 | 336 | { | ||
101 | 337 | TransactionServices::dropTable(*session, *table, *message, if_exists); | ||
102 | 338 | } | ||
103 | 339 | } | ||
104 | 340 | else | ||
105 | 341 | { | ||
106 | 342 | if (local_error == HA_ERR_NO_SUCH_TABLE and if_exists) | ||
107 | 343 | { | ||
108 | 344 | error= 0; | ||
109 | 345 | session->clear_error(); | ||
110 | 346 | } | ||
111 | 347 | |||
112 | 348 | if (local_error == HA_ERR_ROW_IS_REFERENCED) | ||
113 | 349 | { | ||
114 | 350 | /* the table is referenced by a foreign key constraint */ | ||
115 | 351 | foreign_key_error= true; | ||
116 | 352 | } | ||
117 | 353 | error= local_error; | ||
118 | 354 | } | ||
119 | 355 | } | ||
120 | 356 | |||
121 | 357 | if (error) | ||
122 | 358 | { | ||
123 | 359 | wrong_tables.push_back(table->getTableName()); | ||
124 | 360 | } | ||
125 | 361 | } | ||
126 | 362 | |||
127 | 363 | //tables->unlock_table_names(); | ||
128 | 364 | |||
129 | 365 | } while (0); | ||
130 | 366 | |||
131 | 367 | if (wrong_tables.size()) | ||
132 | 368 | { | ||
133 | 369 | if (not foreign_key_error) | ||
134 | 370 | { | ||
135 | 371 | std::string table_error; | ||
136 | 372 | |||
137 | 373 | BOOST_FOREACH(util::string::vector::reference iter, wrong_tables) | ||
138 | 374 | { | ||
139 | 375 | table_error+= iter; | ||
140 | 376 | table_error+= ','; | ||
141 | 377 | } | ||
142 | 378 | table_error.resize(table_error.size() -1); | ||
143 | 379 | |||
144 | 380 | my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), | ||
145 | 381 | table_error.c_str()); | ||
146 | 382 | } | ||
147 | 383 | else | ||
148 | 384 | { | ||
149 | 385 | my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0)); | ||
150 | 386 | } | ||
151 | 387 | error= 1; | ||
152 | 388 | } | ||
153 | 389 | |||
154 | 390 | session->no_warnings_for_error= 0; | ||
155 | 391 | |||
156 | 392 | return error; | ||
157 | 393 | } | ||
158 | 394 | |||
159 | 395 | |||
160 | 253 | /* | 396 | /* |
161 | 254 | Sort keys in the following order: | 397 | Sort keys in the following order: |
162 | 255 | - PRIMARY KEY | 398 | - PRIMARY KEY |
163 | @@ -1278,8 +1421,8 @@ | |||
164 | 1278 | already exists, otherwise we just need to find out if a normal table exists (aka it is fine | 1421 | already exists, otherwise we just need to find out if a normal table exists (aka it is fine |
165 | 1279 | to create a table under a temporary table. | 1422 | to create a table under a temporary table. |
166 | 1280 | */ | 1423 | */ |
169 | 1281 | bool exists= | 1424 | bool exists= |
170 | 1282 | plugin::StorageEngine::doesTableExist(*session, identifier, | 1425 | plugin::StorageEngine::doesTableExist(*session, identifier, |
171 | 1283 | identifier.getType() != message::Table::STANDARD ); | 1426 | identifier.getType() != message::Table::STANDARD ); |
172 | 1284 | 1427 | ||
173 | 1285 | if (exists) | 1428 | if (exists) |
174 | @@ -1344,7 +1487,7 @@ | |||
175 | 1344 | } | 1487 | } |
176 | 1345 | } | 1488 | } |
177 | 1346 | 1489 | ||
179 | 1347 | /* | 1490 | /* |
180 | 1348 | We keep this behind the lock to make sure ordering is correct for a table. | 1491 | We keep this behind the lock to make sure ordering is correct for a table. |
181 | 1349 | This is a very unlikely problem where before we would write out to the | 1492 | This is a very unlikely problem where before we would write out to the |
182 | 1350 | trans log, someone would do a delete/create operation. | 1493 | trans log, someone would do a delete/create operation. |
183 | @@ -1607,11 +1750,11 @@ | |||
184 | 1607 | my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table"); | 1750 | my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table"); |
185 | 1608 | else if (error) | 1751 | else if (error) |
186 | 1609 | { | 1752 | { |
189 | 1610 | my_error(ER_ERROR_ON_RENAME, MYF(0), | 1753 | my_error(ER_ERROR_ON_RENAME, MYF(0), |
190 | 1611 | from.isTmp() ? "#sql-temporary" : from.getSQLPath().c_str(), | 1754 | from.isTmp() ? "#sql-temporary" : from.getSQLPath().c_str(), |
191 | 1612 | to.isTmp() ? "#sql-temporary" : to.getSQLPath().c_str(), error); | 1755 | to.isTmp() ? "#sql-temporary" : to.getSQLPath().c_str(), error); |
192 | 1613 | } | 1756 | } |
194 | 1614 | return error; | 1757 | return error; |
195 | 1615 | } | 1758 | } |
196 | 1616 | 1759 | ||
197 | 1617 | 1760 | ||
198 | @@ -2080,7 +2223,7 @@ | |||
199 | 2080 | if (not was_created) | 2223 | if (not was_created) |
200 | 2081 | { | 2224 | { |
201 | 2082 | plugin::StorageEngine::dropTable(*session, destination_identifier); | 2225 | plugin::StorageEngine::dropTable(*session, destination_identifier); |
203 | 2083 | } | 2226 | } |
204 | 2084 | else | 2227 | else |
205 | 2085 | { | 2228 | { |
206 | 2086 | res= false; | 2229 | res= false; |
207 | 2087 | 2230 | ||
208 | === modified file 'drizzled/sql_table.h' | |||
209 | --- drizzled/sql_table.h 2012-07-11 14:06:00 +0000 | |||
210 | +++ drizzled/sql_table.h 2013-08-22 06:28:00 +0000 | |||
211 | @@ -26,6 +26,7 @@ | |||
212 | 26 | #pragma once | 26 | #pragma once |
213 | 27 | 27 | ||
214 | 28 | #include <drizzled/base.h> | 28 | #include <drizzled/base.h> |
215 | 29 | #include <vector> | ||
216 | 29 | 30 | ||
217 | 30 | namespace drizzled { | 31 | namespace drizzled { |
218 | 31 | 32 | ||
219 | @@ -33,6 +34,7 @@ | |||
220 | 33 | 34 | ||
221 | 34 | int rm_table_part2(Session *session, TableList *tables, bool if_exists, | 35 | int rm_table_part2(Session *session, TableList *tables, bool if_exists, |
222 | 35 | bool drop_temporary); | 36 | bool drop_temporary); |
223 | 37 | int rm_table_part2(Session *session, std::vector<identifier::Table> tables_identifiers, bool if_exists, bool drop_temporary); | ||
224 | 36 | void close_cached_table(Session *session, Table *table); | 38 | void close_cached_table(Session *session, Table *table); |
225 | 37 | 39 | ||
226 | 38 | void wait_while_table_is_used(Session *session, Table *table, | 40 | void wait_while_table_is_used(Session *session, Table *table, |
227 | 39 | 41 | ||
228 | === added file 'plugin/json_server/ddl/table.cc' | |||
229 | --- plugin/json_server/ddl/table.cc 1970-01-01 00:00:00 +0000 | |||
230 | +++ plugin/json_server/ddl/table.cc 2013-08-22 06:28:00 +0000 | |||
231 | @@ -0,0 +1,64 @@ | |||
232 | 1 | /* mode: c; c-basic-offset: 2; indent-tabs-mode: nil; | ||
233 | 2 | * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: | ||
234 | 3 | * | ||
235 | 4 | * Copyright (C) 2011-13 Stewart Smith, Henrik Ingo, Mohit Srivastava | ||
236 | 5 | * | ||
237 | 6 | * This program is free software; you can redistribute it and/or modify | ||
238 | 7 | * it under the terms of the GNU General Public License as published by | ||
239 | 8 | * the Free Software Foundation; either version 2 of the License, or | ||
240 | 9 | * (at your option) any later version. | ||
241 | 10 | * | ||
242 | 11 | * This program is distributed in the hope that it will be useful, | ||
243 | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
244 | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
245 | 14 | * GNU General Public License for more details. | ||
246 | 15 | * | ||
247 | 16 | * You should have received a copy of the GNU General Public License | ||
248 | 17 | * along with this program; if not, write to the Free Software | ||
249 | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
250 | 19 | */ | ||
251 | 20 | /** | ||
252 | 21 | * @file Implements a class Table to handle various operations related to schema.Also it's copy of drizzled/statement/drop_table.cc | ||
253 | 22 | */ | ||
254 | 23 | #include<plugin/json_server/ddl/table.h> | ||
255 | 24 | #include<drizzled/sql_table.h> | ||
256 | 25 | |||
257 | 26 | using namespace std; | ||
258 | 27 | using namespace drizzled; | ||
259 | 28 | |||
260 | 29 | namespace drizzle_plugin{ | ||
261 | 30 | namespace json_server{ | ||
262 | 31 | |||
263 | 32 | bool Table::dropTable() | ||
264 | 33 | { | ||
265 | 34 | bool need_waiting=false; | ||
266 | 35 | if(not _drop_temporary) | ||
267 | 36 | { | ||
268 | 37 | if(session().inTransaction()) | ||
269 | 38 | { | ||
270 | 39 | my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED,MYF(0)); | ||
271 | 40 | return true; | ||
272 | 41 | } | ||
273 | 42 | |||
274 | 43 | if(not(need_waiting=not session().wait_if_global_read_lock(false,true))) | ||
275 | 44 | return true; | ||
276 | 45 | } | ||
277 | 46 | |||
278 | 47 | vector<identifier::Table> tmp_table_identifier; | ||
279 | 48 | tmp_table_identifier.push_back(_table_identifier); | ||
280 | 49 | bool error = rm_table_part2(&session(),tmp_table_identifier,_drop_if_exists,_drop_temporary); | ||
281 | 50 | |||
282 | 51 | if(need_waiting) | ||
283 | 52 | { | ||
284 | 53 | session().startWaitingGlobalReadLock(); | ||
285 | 54 | } | ||
286 | 55 | |||
287 | 56 | if(error) | ||
288 | 57 | return true; | ||
289 | 58 | |||
290 | 59 | session().my_ok(); | ||
291 | 60 | |||
292 | 61 | return false; | ||
293 | 62 | } | ||
294 | 63 | } | ||
295 | 64 | } | ||
296 | 0 | 65 | ||
297 | === added file 'plugin/json_server/ddl/table.h' | |||
298 | --- plugin/json_server/ddl/table.h 1970-01-01 00:00:00 +0000 | |||
299 | +++ plugin/json_server/ddl/table.h 2013-08-22 06:28:00 +0000 | |||
300 | @@ -0,0 +1,61 @@ | |||
301 | 1 | #include <config.h> | ||
302 | 2 | #include <drizzled/session.h> | ||
303 | 3 | #include <drizzled/statement.h> | ||
304 | 4 | |||
305 | 5 | using namespace std; | ||
306 | 6 | using namespace drizzled; | ||
307 | 7 | namespace drizzle_plugin{ | ||
308 | 8 | namespace json_server{ | ||
309 | 9 | /** | ||
310 | 10 | * a class | ||
311 | 11 | * | ||
312 | 12 | * To perform various operation related to dable | ||
313 | 13 | */ | ||
314 | 14 | class Table{ | ||
315 | 15 | public: | ||
316 | 16 | /** | ||
317 | 17 | * Constructor | ||
318 | 18 | * | ||
319 | 19 | * @param in_session a session object. | ||
320 | 20 | * @param table_identifier a identifier::Table object. | ||
321 | 21 | */ | ||
322 | 22 | Table(Session *in_session,identifier::Table table_identifier,bool if_exists,bool drop_temporary):_session(*in_session),_table_identifier(table_identifier),_drop_if_exists(if_exists),_drop_temporary(drop_temporary){} | ||
323 | 23 | /** | ||
324 | 24 | * drop a table. | ||
325 | 25 | * | ||
326 | 26 | * @return false Success | ||
327 | 27 | * @return true Failure | ||
328 | 28 | */ | ||
329 | 29 | bool dropTable(); | ||
330 | 30 | /** | ||
331 | 31 | * Get a session object | ||
332 | 32 | * | ||
333 | 33 | * @return a session object | ||
334 | 34 | */ | ||
335 | 35 | Session& session() const{ | ||
336 | 36 | return _session; | ||
337 | 37 | } | ||
338 | 38 | |||
339 | 39 | private: | ||
340 | 40 | /** | ||
341 | 41 | * Stores a session object. | ||
342 | 42 | */ | ||
343 | 43 | Session& _session; | ||
344 | 44 | /** | ||
345 | 45 | * Stores a identifier::Table object. | ||
346 | 46 | */ | ||
347 | 47 | identifier::Table _table_identifier; | ||
348 | 48 | /** | ||
349 | 49 | * Use for DROP IF EXISTS [TABLE_NAME] | ||
350 | 50 | */ | ||
351 | 51 | bool _drop_if_exists; | ||
352 | 52 | /** | ||
353 | 53 | * Stores whether drop table temporary or not. | ||
354 | 54 | */ | ||
355 | 55 | bool _drop_temporary; | ||
356 | 56 | |||
357 | 57 | |||
358 | 58 | }; | ||
359 | 59 | |||
360 | 60 | } | ||
361 | 61 | } | ||
362 | 0 | 62 | ||
363 | === modified file 'plugin/json_server/json_server.cc' | |||
364 | --- plugin/json_server/json_server.cc 2013-08-13 04:18:28 +0000 | |||
365 | +++ plugin/json_server/json_server.cc 2013-08-22 06:28:00 +0000 | |||
366 | @@ -55,13 +55,13 @@ | |||
367 | 55 | #include <drizzled/pthread_globals.h> | 55 | #include <drizzled/pthread_globals.h> |
368 | 56 | #include <boost/bind.hpp> | 56 | #include <boost/bind.hpp> |
369 | 57 | 57 | ||
370 | 58 | |||
371 | 59 | #include <drizzled/version.h> | 58 | #include <drizzled/version.h> |
372 | 60 | #include <plugin/json_server/json/json.h> | 59 | #include <plugin/json_server/json/json.h> |
373 | 61 | #include <plugin/json_server/db_access.h> | 60 | #include <plugin/json_server/db_access.h> |
374 | 62 | #include <plugin/json_server/http_handler.h> | 61 | #include <plugin/json_server/http_handler.h> |
375 | 63 | #include <plugin/json_server/http_server.h> | 62 | #include <plugin/json_server/http_server.h> |
376 | 64 | #include <plugin/json_server/ddl/schema.h> | 63 | #include <plugin/json_server/ddl/schema.h> |
377 | 64 | #include <plugin/json_server/ddl/table.h> | ||
378 | 65 | #include <plugin/json_server/json_handler.h> | 65 | #include <plugin/json_server/json_handler.h> |
379 | 66 | 66 | ||
380 | 67 | namespace po= boost::program_options; | 67 | namespace po= boost::program_options; |
381 | @@ -82,8 +82,8 @@ | |||
382 | 82 | string default_table; | 82 | string default_table; |
383 | 83 | uint32_t max_threads; | 83 | uint32_t max_threads; |
384 | 84 | uint32_t clone_max_threads=0; | 84 | uint32_t clone_max_threads=0; |
387 | 85 | bool updateSchema(Session *, set_var* var); | 85 | bool updateSchema(Session *, set_var* var); |
388 | 86 | bool updateTable(Session *, set_var* var); | 86 | bool updateTable(Session *, set_var* var); |
389 | 87 | void updateMaxThreads(Session *, sql_var_t); | 87 | void updateMaxThreads(Session *, sql_var_t); |
390 | 88 | static port_constraint port; | 88 | static port_constraint port; |
391 | 89 | 89 | ||
392 | @@ -100,6 +100,7 @@ | |||
393 | 100 | extern "C" void process_json_req(struct evhttp_request *req, void* ); | 100 | extern "C" void process_json_req(struct evhttp_request *req, void* ); |
394 | 101 | extern "C" void process_json_ddl_schema_create_req(struct evhttp_request *req, void* ); | 101 | extern "C" void process_json_ddl_schema_create_req(struct evhttp_request *req, void* ); |
395 | 102 | extern "C" void process_json_ddl_schema_drop_req(struct evhttp_request *req, void* ); | 102 | extern "C" void process_json_ddl_schema_drop_req(struct evhttp_request *req, void* ); |
396 | 103 | extern "C" void process_json_ddl_table_drop_req(struct evhttp_request *req, void* ); | ||
397 | 103 | extern "C" void process_request(struct evhttp_request *req, void* ) | 104 | extern "C" void process_request(struct evhttp_request *req, void* ) |
398 | 104 | { | 105 | { |
399 | 105 | struct evbuffer *buf = evbuffer_new(); | 106 | struct evbuffer *buf = evbuffer_new(); |
400 | @@ -232,7 +233,7 @@ | |||
401 | 232 | 233 | ||
402 | 233 | Json::Value root; | 234 | Json::Value root; |
403 | 234 | root["version"]= ::drizzled::version(); | 235 | root["version"]= ::drizzled::version(); |
405 | 235 | 236 | ||
406 | 236 | Json::StyledWriter writer; | 237 | Json::StyledWriter writer; |
407 | 237 | std::string output= writer.write(root); | 238 | std::string output= writer.write(root); |
408 | 238 | 239 | ||
409 | @@ -321,22 +322,22 @@ | |||
410 | 321 | 322 | ||
411 | 322 | /** | 323 | /** |
412 | 323 | * Transform a HTTP request for sql transaction and return results based on input json document. | 324 | * Transform a HTTP request for sql transaction and return results based on input json document. |
414 | 324 | * | 325 | * |
415 | 325 | * @todo allow DBA to set whether to use strict mode for parsing json (should get rid of white space), especially for POST of course. | 326 | * @todo allow DBA to set whether to use strict mode for parsing json (should get rid of white space), especially for POST of course. |
417 | 326 | * | 327 | * |
418 | 327 | * @param req should contain a "table" parameter in request uri. "query", "_id" and "schema" are optional. | 328 | * @param req should contain a "table" parameter in request uri. "query", "_id" and "schema" are optional. |
419 | 328 | */ | 329 | */ |
420 | 329 | extern "C" void process_json_req(struct evhttp_request *req, void* ) | 330 | extern "C" void process_json_req(struct evhttp_request *req, void* ) |
421 | 330 | { | 331 | { |
422 | 331 | Json::Value json_out; | 332 | Json::Value json_out; |
424 | 332 | Json::Value json_in; | 333 | Json::Value json_in; |
425 | 333 | std::string sql; | 334 | std::string sql; |
426 | 334 | const char* schema; | 335 | const char* schema; |
427 | 335 | const char* table; | 336 | const char* table; |
428 | 336 | 337 | ||
430 | 337 | HttpHandler* handler = new HttpHandler(json_out,json_in,req); | 338 | HttpHandler* handler = new HttpHandler(json_out,json_in,req); |
431 | 338 | if(!handler->handleRequest()) | 339 | if(!handler->handleRequest()) |
433 | 339 | { | 340 | { |
434 | 340 | if(!handler->validate(default_schema,default_table,allow_drop_table)) | 341 | if(!handler->validate(default_schema,default_table,allow_drop_table)) |
435 | 341 | { | 342 | { |
436 | 342 | json_in= handler->getInputJson(); | 343 | json_in= handler->getInputJson(); |
437 | @@ -349,7 +350,7 @@ | |||
438 | 349 | delete(dbAccess); | 350 | delete(dbAccess); |
439 | 350 | } | 351 | } |
440 | 351 | else | 352 | else |
442 | 352 | { | 353 | { |
443 | 353 | json_out= handler->getOutputJson(); | 354 | json_out= handler->getOutputJson(); |
444 | 354 | } | 355 | } |
445 | 355 | } | 356 | } |
446 | @@ -367,7 +368,7 @@ | |||
447 | 367 | * | 368 | * |
448 | 368 | * @param req a HTTP request parameter, | 369 | * @param req a HTTP request parameter, |
449 | 369 | * | 370 | * |
451 | 370 | */ | 371 | */ |
452 | 371 | 372 | ||
453 | 372 | extern "C" void process_json_ddl_schema_create_req(struct evhttp_request *req, void* ) | 373 | extern "C" void process_json_ddl_schema_create_req(struct evhttp_request *req, void* ) |
454 | 373 | { | 374 | { |
455 | @@ -405,7 +406,7 @@ | |||
456 | 405 | struct evbuffer *buf = evbuffer_new(); | 406 | struct evbuffer *buf = evbuffer_new(); |
457 | 406 | if(buf == NULL) | 407 | if(buf == NULL) |
458 | 407 | { | 408 | { |
460 | 408 | return; | 409 | return; |
461 | 409 | } | 410 | } |
462 | 410 | evbuffer_add(buf, output.c_str(), output.length()); | 411 | evbuffer_add(buf, output.c_str(), output.length()); |
463 | 411 | evhttp_send_reply( req, http_response_code, http_response_text, buf); | 412 | evhttp_send_reply( req, http_response_code, http_response_text, buf); |
464 | @@ -413,7 +414,7 @@ | |||
465 | 413 | 414 | ||
466 | 414 | /** | 415 | /** |
467 | 415 | * Transform a HTTP Request for create schema and returns results based on the input json. | 416 | * Transform a HTTP Request for create schema and returns results based on the input json. |
469 | 416 | * | 417 | * |
470 | 417 | * @param req a HTTP request parameter. | 418 | * @param req a HTTP request parameter. |
471 | 418 | */ | 419 | */ |
472 | 419 | extern "C" void process_json_ddl_schema_drop_req(struct evhttp_request *req, void* ) | 420 | extern "C" void process_json_ddl_schema_drop_req(struct evhttp_request *req, void* ) |
473 | @@ -423,7 +424,7 @@ | |||
474 | 423 | drizzled::identifier::user::mptr user_id= identifier::User::make_shared(); | 424 | drizzled::identifier::user::mptr user_id= identifier::User::make_shared(); |
475 | 424 | _session->main_da().reset_diagnostics_area(); | 425 | _session->main_da().reset_diagnostics_area(); |
476 | 425 | setCurrentSession(_session.get()); | 426 | setCurrentSession(_session.get()); |
478 | 426 | 427 | ||
479 | 427 | std::string query; | 428 | std::string query; |
480 | 428 | std::string db_name; | 429 | std::string db_name; |
481 | 429 | std::string output; | 430 | std::string output; |
482 | @@ -431,7 +432,7 @@ | |||
483 | 431 | Json::Value json_in; | 432 | Json::Value json_in; |
484 | 432 | const char *http_response_text="OK"; | 433 | const char *http_response_text="OK"; |
485 | 433 | int http_response_code=HTTP_OK; | 434 | int http_response_code=HTTP_OK; |
487 | 434 | 435 | ||
488 | 435 | JsonErrorArea _json_error; | 436 | JsonErrorArea _json_error; |
489 | 436 | JsonHandler* _json_handler = new JsonHandler(); | 437 | JsonHandler* _json_handler = new JsonHandler(); |
490 | 437 | 438 | ||
491 | @@ -454,11 +455,69 @@ | |||
492 | 454 | if(buf == NULL) | 455 | if(buf == NULL) |
493 | 455 | { | 456 | { |
494 | 456 | return; | 457 | return; |
500 | 457 | } | 458 | } |
501 | 458 | evbuffer_add(buf, output.c_str(), output.length()); | 459 | evbuffer_add(buf, output.c_str(), output.length()); |
502 | 459 | evhttp_send_reply( req, http_response_code, http_response_text, buf); | 460 | evhttp_send_reply( req, http_response_code, http_response_text, buf); |
503 | 460 | } | 461 | } |
504 | 461 | 462 | ||
505 | 463 | /** | ||
506 | 464 | * Transform a HTTP Request for drop table and returns results based on the input json. | ||
507 | 465 | * | ||
508 | 466 | * @param req a HTTP request parameter. | ||
509 | 467 | */ | ||
510 | 468 | extern "C" void process_json_ddl_table_drop_req(struct evhttp_request *req, void* ) | ||
511 | 469 | { | ||
512 | 470 | drizzled::Session::shared_ptr _session= drizzled::Session::make_shared(drizzled::plugin::Listen::getNullClient(), | ||
513 | 471 | drizzled::catalog::local()); | ||
514 | 472 | drizzled::identifier::user::mptr user_id= identifier::User::make_shared(); | ||
515 | 473 | _session->main_da().reset_diagnostics_area(); | ||
516 | 474 | setCurrentSession(_session.get()); | ||
517 | 475 | |||
518 | 476 | std::string query; | ||
519 | 477 | std::string table_name; | ||
520 | 478 | std::string schema_name; | ||
521 | 479 | std::string output; | ||
522 | 480 | bool if_exists = false; | ||
523 | 481 | Json::Value json_out; | ||
524 | 482 | Json::Value json_in; | ||
525 | 483 | const char *http_response_text="OK"; | ||
526 | 484 | int http_response_code=HTTP_OK; | ||
527 | 485 | |||
528 | 486 | JsonErrorArea _json_error; | ||
529 | 487 | JsonHandler* _json_handler = new JsonHandler(); | ||
530 | 488 | |||
531 | 489 | _json_handler->generate_input_json(req,_json_error); | ||
532 | 490 | if(!_json_error.is_jsonerror()) | ||
533 | 491 | { | ||
534 | 492 | json_in = _json_handler->get_input_json(); | ||
535 | 493 | |||
536 | 494 | table_name=json_in["query"]["table_name"].asString(); | ||
537 | 495 | schema_name=json_in["query"]["schema_name"].asString(); | ||
538 | 496 | if(!json_in["query"]["if_exists"].empty()) | ||
539 | 497 | { | ||
540 | 498 | if(strcmp(json_in["query"]["if_exists"].asCString(),"true")==0) | ||
541 | 499 | { | ||
542 | 500 | if_exists=true; | ||
543 | 501 | } | ||
544 | 502 | } | ||
545 | 503 | identifier::Table table_identifier(_session->catalog().identifier(),schema_name,table_name); | ||
546 | 504 | Table *_table= new Table(_session.get(),table_identifier,if_exists,false); | ||
547 | 505 | _table->dropTable(); | ||
548 | 506 | if(_session->main_da().is_error()) | ||
549 | 507 | { | ||
550 | 508 | _json_error.set_error(JsonErrorArea::ER_SQL,_session->main_da().sql_errno(),_session->main_da().message()); | ||
551 | 509 | } | ||
552 | 510 | } | ||
553 | 511 | _json_handler->generate_output_query(_json_error); | ||
554 | 512 | output = _json_handler->get_output_query(); | ||
555 | 513 | struct evbuffer *buf = evbuffer_new(); | ||
556 | 514 | if(buf == NULL) | ||
557 | 515 | { | ||
558 | 516 | return; | ||
559 | 517 | } | ||
560 | 518 | evbuffer_add(buf, output.c_str(), output.length()); | ||
561 | 519 | evhttp_send_reply( req, http_response_code, http_response_text, buf); | ||
562 | 520 | } | ||
563 | 462 | 521 | ||
564 | 463 | static void shutdown_event(int fd, short, void *arg) | 522 | static void shutdown_event(int fd, short, void *arg) |
565 | 464 | { | 523 | { |
566 | @@ -520,18 +579,19 @@ | |||
567 | 520 | sql_perror("evhttp_bind_socket()"); | 579 | sql_perror("evhttp_bind_socket()"); |
568 | 521 | return false; | 580 | return false; |
569 | 522 | } | 581 | } |
571 | 523 | 582 | ||
572 | 524 | // Create Max_thread number of threads. | 583 | // Create Max_thread number of threads. |
573 | 525 | if(not createThreads(max_threads)) | 584 | if(not createThreads(max_threads)) |
574 | 526 | { | 585 | { |
575 | 527 | return false; | 586 | return false; |
576 | 528 | } | 587 | } |
578 | 529 | 588 | ||
579 | 530 | return true; | 589 | return true; |
580 | 531 | } | 590 | } |
581 | 532 | 591 | ||
582 | 533 | bool createThreads(uint32_t num_threads) | 592 | bool createThreads(uint32_t num_threads) |
583 | 534 | { | 593 | { |
584 | 594 | num_threads=1; | ||
585 | 535 | for(uint32_t i =0;i<num_threads;i++) | 595 | for(uint32_t i =0;i<num_threads;i++) |
586 | 536 | { | 596 | { |
587 | 537 | if ((base= event_init()) == NULL) | 597 | if ((base= event_init()) == NULL) |
588 | @@ -552,7 +612,7 @@ | |||
589 | 552 | return false; | 612 | return false; |
590 | 553 | } | 613 | } |
591 | 554 | 614 | ||
593 | 555 | // These URLs are available. Bind worker method to each of them. | 615 | // These URLs are available. Bind worker method to each of them. |
594 | 556 | evhttp_set_cb(httpd, "/", process_root_request, NULL); | 616 | evhttp_set_cb(httpd, "/", process_root_request, NULL); |
595 | 557 | // API 0.1 | 617 | // API 0.1 |
596 | 558 | evhttp_set_cb(httpd, "/0.1/version", process_api01_version_req, NULL); | 618 | evhttp_set_cb(httpd, "/0.1/version", process_api01_version_req, NULL); |
597 | @@ -571,21 +631,19 @@ | |||
598 | 571 | evhttp_set_cb(httpd, "/json", process_json_req, NULL); | 631 | evhttp_set_cb(httpd, "/json", process_json_req, NULL); |
599 | 572 | evhttp_set_cb(httpd,"/json/ddl/schema/create", process_json_ddl_schema_create_req, NULL); | 632 | evhttp_set_cb(httpd,"/json/ddl/schema/create", process_json_ddl_schema_create_req, NULL); |
600 | 573 | evhttp_set_cb(httpd,"/json/ddl/schema/drop", process_json_ddl_schema_drop_req, NULL); | 633 | evhttp_set_cb(httpd,"/json/ddl/schema/drop", process_json_ddl_schema_drop_req, NULL); |
616 | 574 | 634 | evhttp_set_cb(httpd,"/json/ddl/table/drop", process_json_ddl_table_drop_req, NULL); | |
617 | 575 | 635 | event_set(&wakeup_event, wakeup_fd[0], EV_READ | EV_PERSIST, shutdown_event, base); | |
618 | 576 | event_set(&wakeup_event, wakeup_fd[0], EV_READ | EV_PERSIST, shutdown_event, base); | 636 | event_base_set(base, &wakeup_event); |
619 | 577 | event_base_set(base, &wakeup_event); | 637 | if (event_add(&wakeup_event, NULL) < 0) |
620 | 578 | if (event_add(&wakeup_event, NULL) < 0) | 638 | { |
621 | 579 | { | 639 | sql_perror("event_add"); |
622 | 580 | sql_perror("event_add"); | 640 | return false; |
623 | 581 | return false; | 641 | } |
624 | 582 | } | 642 | drizzled::thread_ptr local_thread; |
625 | 583 | drizzled::thread_ptr local_thread; | 643 | local_thread.reset(new boost::thread((boost::bind(&run, base)))); |
626 | 584 | local_thread.reset(new boost::thread((boost::bind(&run, base)))); | 644 | json_threads.push_back(local_thread); |
627 | 585 | json_threads.push_back(local_thread); | 645 | if (not json_threads[i]) |
628 | 586 | 646 | return false; | |
614 | 587 | if (not json_threads[i]) | ||
615 | 588 | return false; | ||
629 | 589 | } | 647 | } |
630 | 590 | return true; | 648 | return true; |
631 | 591 | } | 649 | } |
632 | @@ -654,7 +712,7 @@ | |||
633 | 654 | 712 | ||
634 | 655 | static int json_server_init(drizzled::module::Context &context) | 713 | static int json_server_init(drizzled::module::Context &context) |
635 | 656 | { | 714 | { |
637 | 657 | 715 | ||
638 | 658 | server = new JsonServer(port); | 716 | server = new JsonServer(port); |
639 | 659 | context.add(server); | 717 | context.add(server); |
640 | 660 | context.registerVariable(new sys_var_constrained_value_readonly<in_port_t>("port", port)); | 718 | context.registerVariable(new sys_var_constrained_value_readonly<in_port_t>("port", port)); |
641 | @@ -662,7 +720,7 @@ | |||
642 | 662 | context.registerVariable(new sys_var_std_string("table", default_table, NULL, &updateTable)); | 720 | context.registerVariable(new sys_var_std_string("table", default_table, NULL, &updateTable)); |
643 | 663 | context.registerVariable(new sys_var_bool_ptr("allow_drop_table", &allow_drop_table)); | 721 | context.registerVariable(new sys_var_bool_ptr("allow_drop_table", &allow_drop_table)); |
644 | 664 | context.registerVariable(new sys_var_uint32_t_ptr("max_threads",&max_threads,&updateMaxThreads)); | 722 | context.registerVariable(new sys_var_uint32_t_ptr("max_threads",&max_threads,&updateMaxThreads)); |
646 | 665 | 723 | ||
647 | 666 | clone_max_threads=max_threads; | 724 | clone_max_threads=max_threads; |
648 | 667 | 725 | ||
649 | 668 | 726 | ||
650 | 669 | 727 | ||
651 | === modified file 'plugin/json_server/plugin.ini' | |||
652 | --- plugin/json_server/plugin.ini 2013-07-28 08:33:01 +0000 | |||
653 | +++ plugin/json_server/plugin.ini 2013-08-22 06:28:00 +0000 | |||
654 | @@ -1,7 +1,7 @@ | |||
655 | 1 | [plugin] | 1 | [plugin] |
656 | 2 | headers= | 2 | headers= |
657 | 3 | sql_generator.h | 3 | sql_generator.h |
659 | 4 | sql_executor.h | 4 | sql_executor.h |
660 | 5 | sql_to_json_generator.h | 5 | sql_to_json_generator.h |
661 | 6 | http_handler.h | 6 | http_handler.h |
662 | 7 | http_server.h | 7 | http_server.h |
663 | @@ -9,6 +9,7 @@ | |||
664 | 9 | error.h | 9 | error.h |
665 | 10 | db_access.h | 10 | db_access.h |
666 | 11 | ddl/schema.h | 11 | ddl/schema.h |
667 | 12 | ddl/table.h | ||
668 | 12 | json/autolink.h | 13 | json/autolink.h |
669 | 13 | json/config.h | 14 | json/config.h |
670 | 14 | json/features.h | 15 | json/features.h |
671 | @@ -32,6 +33,7 @@ | |||
672 | 32 | error.cc | 33 | error.cc |
673 | 33 | db_access.cc | 34 | db_access.cc |
674 | 34 | ddl/schema.cc | 35 | ddl/schema.cc |
675 | 36 | ddl/table.cc | ||
676 | 35 | json/json_reader.cpp | 37 | json/json_reader.cpp |
677 | 36 | json/json_value.cpp | 38 | json/json_value.cpp |
678 | 37 | json/json_writer.cpp | 39 | json/json_writer.cpp |
679 | 38 | 40 | ||
680 | === modified file 'plugin/json_server/tests/r/basic.result' | |||
681 | --- plugin/json_server/tests/r/basic.result 2013-07-28 08:33:01 +0000 | |||
682 | +++ plugin/json_server/tests/r/basic.result 2013-08-22 06:28:00 +0000 | |||
683 | @@ -305,3 +305,30 @@ | |||
684 | 305 | "error_type" : "SQL ERROR", | 305 | "error_type" : "SQL ERROR", |
685 | 306 | "sql_state" : "HY000" | 306 | "sql_state" : "HY000" |
686 | 307 | } | 307 | } |
687 | 308 | create schema json; | ||
688 | 309 | create table json.test (a int); | ||
689 | 310 | { | ||
690 | 311 | "error_message" : "Unknown table 'test'", | ||
691 | 312 | "error_no" : 1051, | ||
692 | 313 | "error_type" : "SQL ERROR", | ||
693 | 314 | "sql_state" : "42S02" | ||
694 | 315 | } | ||
695 | 316 | { | ||
696 | 317 | "sql_state" : "00000" | ||
697 | 318 | } | ||
698 | 319 | { | ||
699 | 320 | "error_message" : "Unknown table 'test'", | ||
700 | 321 | "error_no" : 1051, | ||
701 | 322 | "error_type" : "SQL ERROR", | ||
702 | 323 | "sql_state" : "42S02" | ||
703 | 324 | } | ||
704 | 325 | { | ||
705 | 326 | "sql_state" : "00000" | ||
706 | 327 | } | ||
707 | 328 | { | ||
708 | 329 | "error_message" : "Unknown table 'test'", | ||
709 | 330 | "error_no" : 1051, | ||
710 | 331 | "error_type" : "SQL ERROR", | ||
711 | 332 | "sql_state" : "42S02" | ||
712 | 333 | } | ||
713 | 334 | drop schema json; | ||
714 | 308 | 335 | ||
715 | === modified file 'plugin/json_server/tests/t/basic.test' | |||
716 | --- plugin/json_server/tests/t/basic.test 2013-08-13 04:18:28 +0000 | |||
717 | +++ plugin/json_server/tests/t/basic.test 2013-08-22 06:28:00 +0000 | |||
718 | @@ -92,3 +92,20 @@ | |||
719 | 92 | --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' | 92 | --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' |
720 | 93 | 93 | ||
721 | 94 | --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' | 94 | --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' |
722 | 95 | |||
723 | 96 | create schema json; | ||
724 | 97 | |||
725 | 98 | create table json.test (a int); | ||
726 | 99 | |||
727 | 100 | --exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"schema_name":"json_test","table_name":"test"}}' 'http://localhost:$JSON_SERVER_PORT/json/ddl/table/drop' | ||
728 | 101 | |||
729 | 102 | --exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"schema_name":"json","table_name":"test"}}' 'http://localhost:$JSON_SERVER_PORT/json/ddl/table/drop' | ||
730 | 103 | |||
731 | 104 | --exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"schema_name":"json","table_name":"test"}}' 'http://localhost:$JSON_SERVER_PORT/json/ddl/table/drop' | ||
732 | 105 | |||
733 | 106 | --exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"schema_name":"json","table_name":"test","if_exists":"true"}}' 'http://localhost:$JSON_SERVER_PORT/json/ddl/table/drop' | ||
734 | 107 | |||
735 | 108 | --exec curl -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{"query":{"schema_name":"json","table_name":"test","if_exists":"false"}}' 'http://localhost:$JSON_SERVER_PORT/json/ddl/table/drop' | ||
736 | 109 | |||
737 | 110 | drop schema json; | ||
738 | 111 |