rikitiki  v0.1.67
Build C++ web server modules that allow easy routing and deployment.
rest.h
1 /* Copyright (C) 2012-2013 Justin Berger
2  The full license is available in the LICENSE file at the root of this project and is also available at http://opensource.org/licenses/MIT. */
3 #pragma once
4 #include <rikitiki/rikitiki>
5 #include <rikitiki/mongoose/mongoose>
6 #include <rikitiki/rest/rest>
7 #include <rikitiki/jsoncpp/jsoncpp>
8 #include <rikitiki/configuration/configuration>
9 #include <sqlite3.h>
10 
11 using namespace rikitiki;
12 using namespace rikitiki::mongoose;
13 
14 namespace rikitiki {
15  namespace examples {
22  struct RestModule {
23  static const char* create_table,*select_all,*select,*insert;
24  sqlite3_stmt *insert_stmt, *select_all_stmt, *select_stmt;
25  sqlite3* handle;
26 
28  void throwNQ(ConnContext& ctx, int retval, int desired_retval){
29  if(retval != desired_retval){
30  ctx.response.reset();
31  ctx << "Sqlite3 err code: " << retval << "\n"
32  << sqlite3_errmsg(handle);
33  throw HandlerException();
34  }
35  }
36 
38  Json::Value readRow(sqlite3_stmt* stmt){
39  Json::Value row;
40  row["id"] = sqlite3_column_int(stmt, 0);
41  row["name"] = std::string((const char*)sqlite3_column_text(stmt, 1));
42  row["author"] = std::string((const char*)sqlite3_column_text(stmt, 2));
43  row["isbn"] = std::string((const char*)sqlite3_column_text(stmt, 3));
44  return row;
45  }
46 
48  void POST(ConnContext& ctx){
49  Json::Value val;
50  ctx >> val;
51  std::string name = val["name"].asString();
52  std::string author = val["author"].asString();
53  std::string isbn = val["isbn"].asString();
54 
55  sqlite3_reset(insert_stmt);
56  throwNQ(ctx, sqlite3_bind_text(insert_stmt, 1, &name[0], name.size(), SQLITE_TRANSIENT), SQLITE_OK);
57  throwNQ(ctx, sqlite3_bind_text(insert_stmt, 2, &author[0], author.size(), SQLITE_TRANSIENT), SQLITE_OK);
58  throwNQ(ctx, sqlite3_bind_text(insert_stmt, 3, &isbn[0], isbn.size(), SQLITE_TRANSIENT), SQLITE_OK);
59  throwNQ(ctx, sqlite3_step(insert_stmt), SQLITE_DONE);
60  ctx << sqlite3_last_insert_rowid(handle);
61  }
62 
64  void GET(ConnContext& ctx){
65  Json::Value val(Json::arrayValue);
66  int retval;
67 
68  sqlite3_reset(select_all_stmt);
69 
70  while((retval = sqlite3_step(select_all_stmt)) == SQLITE_ROW)
71  val.append(readRow(select_all_stmt));
72 
73  throwNQ(ctx, retval, SQLITE_DONE);
74  ctx << val;
75  }
76 
77  void GET(ConnContext& ctx, int id){
78  sqlite3_reset(select_stmt);
79  sqlite3_bind_int(select_stmt, 1, id);
80  if(sqlite3_step(select_stmt) == SQLITE_ROW)
81  ctx << readRow(select_stmt);
82  else
83  ctx << Json::Value();
84  }
85 
86  void DELETE(ConnContext& ctx){
87  char* error;
88  sqlite3_exec(handle,"DELETE from books", 0, 0, &error);
89  if(error){
90  ctx << error;
91  throw HandlerException{};
92  }
93  sqlite3_exec(handle,create_table,0,0,0);
94  ctx.handled = true; // If we don't write anything to ctx, it doesn't count as handled.
95  }
96 
97  void init_db(){
98  sqlite3_exec(handle,create_table,0,0,0);
99  sqlite3_prepare_v2(handle, insert, strlen(insert), &insert_stmt, NULL);
100  sqlite3_prepare_v2(handle, select_all, strlen(select_all), &select_all_stmt, NULL);
101  sqlite3_prepare_v2(handle, select, strlen(select), &select_stmt, NULL);
102  }
103 
104  RestModule() {
105  int retval = sqlite3_open_v2(":memory:", &handle, SQLITE_OPEN_READWRITE, 0);
106  if(retval){
107  LOG(Rest, Error) << "Sqlite3 err code: " << retval << std::endl << sqlite3_errmsg(handle) << std::endl;
108  } else {
109  init_db();
110  }
111  }
112 
113  void Register(Server& server){
114  typedef RestModule T;
115  rikitiki::rest::Register(server, "/book", this);
116  }
117  };
118 
119  const char* RestModule::insert = "insert into books (name, author, isbn) values (?, ?, ?)";
120  const char* RestModule::create_table = "create table if not exists books (id INTEGER PRIMARY KEY, name TEXT NOT NULL, author TEXT NOT NULL, isbn TEXT NOT NULL)";
121  const char* RestModule::select_all = "select id, name, author, isbn from books;";
122  const char* RestModule::select = "select id, name, author, isbn from books where id = ?;";
123  }
124 }