00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef cave_h
00023 #define cave_h
00024
00025 #ifndef _REENTRANT
00026 #define _REENTRANT
00027 #endif
00028
00029 #include "config.h"
00030 #include "data.h"
00031 #include "log.h"
00032 #include "rock.h"
00033 #include "util.h"
00034 #include "db.h"
00035 #include "fab.h"
00036 #include "stream.h"
00037 #include "cave_protocol.h"
00038 #include <pqxx/pqxx>
00039 #include <vector>
00040 #include <map>
00041
00042 using std::vector;
00043 using std::map;
00044
00191 namespace karoo {
00192
00193 class cave_handler;
00194 class cave_service;
00195 class cave_element;
00196
00197 class cave : public rock
00198 {
00199 public:
00200 class mime_type : public referable
00201 {
00202 public:
00203 text ext;
00204 text type;
00205 mime_type(const text& ext, const text& type) { this->ext = ext; this->type = type; }
00206 virtual ~mime_type() {}
00207 };
00208 private:
00209 text root;
00210
00211 int http_port;
00212 time_t http_timeout;
00213 stream_service* service;
00214 stream_factory* factory;
00215 HTTP_handler_factory* handler_factory;
00216 khashe mime_types;
00217 exeque* listenq;
00218 exeque* streamq;
00219 exeque* httpq;
00220
00221 db* database;
00222 mutable karoo_mutex db_sem;
00223 mutable karoo_mutex service_sem;
00224 map<text,cave_service*> services;
00225
00226 class cave_config: public pebble
00227 {
00228 private:
00229 time_t poll_delay;
00230 cave* parent;
00231 text url;
00232 text dbname;
00233 map<text,cave_service*> services;
00234 cave_service* getService(const text& id);
00235 void add(const text& id, cave_service* svc);
00236 text connection_str;
00237 size_t connection_pool_size;
00238 public:
00239 cave_config(cave* parent, text url, time_t poll_delay);
00240 virtual ~cave_config();
00241
00242 void run();
00243 bool traverse(fab& conf, nxml_data_t* node, cave_element* context);
00244 };
00245 public:
00246 cave(const vector<text>& opts, int argc, char *argv[]);
00247 void startup(const text& url, time_t poll_delay);
00248 virtual ~cave();
00249
00250 void stop();
00251 text getType() const { return "cave"; }
00252 void initialiseDatabase(const text& conf, size_t pool_sz = 1);
00253 void initialiseDatabaseAndServices(const text& conf, size_t pool_sz, map<text,cave_service*>& services);
00254 cave_service* getService(const text& id);
00255 void add(const text& id, cave_service* svc);
00256 db* getDatabase() { return database; }
00257 void clearServices();
00258
00259 bool getMimeType(const text& ext, text& type);
00260 void setMimeType(const text& ext, const text& type);
00261 text getRoot() const { return root; }
00262 };
00263
00264 class cave_HTTP_handler_factory: public HTTP_handler_factory {
00265 private:
00266 cave* parent;
00267 public:
00268 cave_HTTP_handler_factory(cave* parent) { this->parent = parent; }
00269 virtual ~cave_HTTP_handler_factory() {}
00270
00271 HTTP_handler* create_HTTP_handler(HTTP_parsed_data* data);
00272 };
00273
00274 class cave_HTTP_handler: public HTTP_handler {
00275 private:
00276 cave* parent;
00277 bool head;
00278 size_t length;
00279 public:
00280 cave_HTTP_handler(HTTP_parsed_data* data, cave* parent, bool head = false);
00281 virtual ~cave_HTTP_handler();
00282
00283 virtual bool run();
00284
00285 void writeBack(const text& column_name, uint32_t uval, uint32_t row_count, cave_service* service);
00286 void writeBack(const text& column_name, uint64_t uval, uint32_t row_count, cave_service* service);
00287 void writeBack(const text& column_name, int32_t ival, uint32_t row_count, cave_service* service);
00288 void writeBack(const text& column_name, int64_t ival, uint32_t row_count, cave_service* service);
00289 void writeBack(const text& column_name, double dval, uint32_t row_count, cave_service* service);
00290 void writeBack(const text& column_name, long double ldval, uint32_t row_count, cave_service* service);
00291 void writeBack(const text& column_name, const text& tval, uint32_t row_count, cave_service* service);
00292 };
00293
00294
00295 class cave_handler: public rock_datagram_message_handler
00296 {
00297 public:
00298 cave_handler(cave* parent) : rock_datagram_message_handler(parent) {}
00299 virtual ~cave_handler() {}
00300 bool handle(uint32_t msg_type, uint64_t seq, int32_t port, const text& name, rock_datagram_message* msg);
00301 };
00302
00303 class cave_context_data: public referable
00304 {
00305 public:
00306 union {
00307 uint8_t u8;
00308 bool b;
00309 char c;
00310 uint16_t u16;
00311 uint32_t u32;
00312 uint64_t u64;
00313 int8_t i8;
00314 int16_t i16;
00315 int32_t i32;
00316 int64_t i64;
00317 float f;
00318 double d;
00319 long double ld;
00320 } val;
00321 text s;
00322
00323 enum db_data_type type;
00324
00325 cave_context_data() {}
00326 virtual ~cave_context_data() {}
00327 };
00328
00329 class cave_service;
00330
00331 class cave_context: public pebble
00332 {
00333 private:
00334 cave_service* service;
00335 cave_handler* handler;
00336 cave_HTTP_handler* http_handler;
00337 uint32_t msg_type;
00338 uint64_t seq;
00339 int32_t port;
00340 text name;
00341 rock_datagram_message* msg;
00342 text reply_id_string;
00343 uint64_t reply_id_number;
00344 map<text,cave_context_data*> params;
00345 public:
00346 cave_context(cave_service* service, cave_HTTP_handler* http_handler);
00347 cave_context(cave_service* service, cave_handler* handler, uint32_t msg_type, uint64_t seq, int32_t port, const text& name, rock_datagram_message* msg, const text& reply_id_string, uint64_t reply_id_number);
00348 virtual ~cave_context();
00349
00350 void setParameter(const text& key, cave_context_data* val);
00351 const cave_context_data* getParameter(const text& key) const;
00352
00353 cave_service* getService() { return service; }
00354 cave_handler* getHandler() { return handler; }
00355 cave_HTTP_handler* getHTTPHandler() { return http_handler; }
00356 uint32_t getMsgType() const { return msg_type; }
00357 uint64_t getSeq() const { return seq; }
00358 int32_t getPort() const { return port; }
00359 text getName() const { return name; }
00360 const rock_datagram_message* getMessage() const { return msg; }
00361 text getReplyIdString() const { return reply_id_string; }
00362 uint64_t getReplyIdNumber() const { return reply_id_number; }
00363 void run();
00364 };
00365
00366 enum cave_element_type {
00367 CAVE_ELEMENT_TYPE_SERVICE = 0,
00368 CAVE_ELEMENT_TYPE_SQL,
00369 };
00370
00371 class cave_element: public referable
00372 {
00373 protected:
00374 enum cave_element_type type;
00375 public:
00376 cave_element(enum cave_element_type type) { this->type = type; }
00377 virtual ~cave_element() {}
00378 enum cave_element_type getType() const { return type; }
00379 virtual void run(cave_context* context) = 0;
00380 };
00381
00382 class cave_sql;
00383
00384 class cave_service: public cave_element
00385 {
00386 private:
00387 text name;
00388 text id;
00389 vector<cave_sql*> sqls;
00390 karoo_mutex sqls_sem;
00391 cave* parent;
00392 public:
00393 cave_service(cave* parent, const text& name, const text& id);
00394 virtual ~cave_service();
00395 void add(cave_sql*);
00396 cave* getParent() { return parent; }
00397
00398 void run(cave_context* context);
00399 };
00400
00401 class cave_sql_component;
00402
00403 class cave_sql: public cave_element
00404 {
00405 private:
00406 vector<cave_sql_component*> components;
00407 karoo_mutex components_sem;
00408 cave_service* parent;
00409 bool commit;
00410 public:
00411 cave_sql(cave_service* parent, bool commit);
00412 virtual ~cave_sql();
00413 void add(cave_sql_component* component);
00414
00415 void run(cave_context* context);
00416 cave_service* getParent() { return parent; }
00417 };
00418
00419 enum cave_sql_component_type {
00420 CAVE_SQL_COMPONENT_TYPE_TEXT = 0,
00421 CAVE_SQL_COMPONENT_TYPE_PARAMETER,
00422 };
00423
00424 class cave_sql_component: public referable
00425 {
00426 protected:
00427 enum cave_sql_component_type type;
00428 cave_context* context;
00429 public:
00430 cave_sql_component(enum cave_sql_component_type type) { this->type = type; }
00431 virtual ~cave_sql_component() {}
00432 void setContext(cave_context* context) { this->context = context; }
00433 virtual void writeOut(text& out) const = 0;
00434 };
00435
00436 extern text& operator<<(text& out, const cave_sql_component& component);
00437
00438 class cave_sql_text : public cave_sql_component
00439 {
00440 private:
00441 text value;
00442 public:
00443 cave_sql_text(const text& value);
00444 virtual ~cave_sql_text();
00445 void writeOut(text& out) const;
00446 };
00447
00448 enum cave_sql_parameter_type {
00449 CAVE_SQL_PARAMETER_TYPE_QUOTED_STRING = 0,
00450 CAVE_SQL_PARAMETER_TYPE_IMAGE,
00451 CAVE_SQL_PARAMETER_TYPE_ESCAPED_STRING,
00452 CAVE_SQL_PARAMETER_TYPE_BOOLEAN,
00453 CAVE_SQL_PARAMETER_TYPE_INTEGER,
00454 CAVE_SQL_PARAMETER_TYPE_UNSIGNED,
00455 CAVE_SQL_PARAMETER_TYPE_FLOAT,
00456 };
00457
00458 class cave_sql_parameter: public cave_sql_component
00459 {
00460 private:
00461 cave_sql* parent;
00462 text name;
00463 enum cave_sql_parameter_type type;
00464 unsigned width;
00465 unsigned height;
00466 public:
00467 cave_sql_parameter(cave_sql* parent, const text& name, enum cave_sql_parameter_type type, unsigned width = 0, unsigned height = 0);
00468 virtual ~cave_sql_parameter();
00469 void writeOut(text& out) const;
00470 };
00471 }
00472
00473 #endif