Mercurial > thymian
comparison cppdb/cppdb.h @ 0:a4671277546c tip
created the repository for the thymian project
| author | ferencd |
|---|---|
| date | Tue, 17 Aug 2021 11:19:54 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:a4671277546c |
|---|---|
| 1 #ifndef CPPDB_H | |
| 2 #define CPPDB_H | |
| 3 | |
| 4 #include <string> | |
| 5 #include <common.h> | |
| 6 #include <tuple> | |
| 7 #include <functional> | |
| 8 #include <type_traits> | |
| 9 #include <algorithm> | |
| 10 | |
| 11 #define _O(x) x | |
| 12 | |
| 13 // helper macros | |
| 14 #define CONCAT_IMPL( x, y ) x##y | |
| 15 #define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y ) | |
| 16 | |
| 17 // basic value retrieval for various column types | |
| 18 struct value_renderer | |
| 19 { | |
| 20 value_renderer() = default; | |
| 21 virtual ~value_renderer() = default; | |
| 22 virtual std::string render(const std::string& t) const { return t; } | |
| 23 | |
| 24 virtual std::string value() const = 0; | |
| 25 virtual std::string crypted(bool) = 0; | |
| 26 virtual value_renderer& decrypted(bool) = 0; | |
| 27 | |
| 28 }; | |
| 29 | |
| 30 /** | |
| 31 * Class representing a column | |
| 32 */ | |
| 33 class Column | |
| 34 { | |
| 35 public: | |
| 36 virtual ~Column() = default; | |
| 37 virtual std::string name() const = 0; | |
| 38 virtual std::string realname() const = 0; | |
| 39 virtual std::string type() const = 0; | |
| 40 virtual const value_renderer* get_value_renderer() const = 0; | |
| 41 virtual std::string extra_modifiers() const = 0; | |
| 42 virtual std::string crypt_value(const std::string&) const = 0; | |
| 43 virtual std::string decrypt_value(const std::string&) const = 0; | |
| 44 virtual Column* clone() const = 0; | |
| 45 }; | |
| 46 | |
| 47 class BasicColumn : public Column | |
| 48 { | |
| 49 public: | |
| 50 virtual std::string name() const { return "" ;} | |
| 51 virtual std::string type() const { return "" ;} | |
| 52 virtual std::string extra_modifiers() const { return "";} | |
| 53 }; | |
| 54 | |
| 55 class NotAColumn : public Column | |
| 56 { | |
| 57 public: | |
| 58 virtual std::string name() const = 0; | |
| 59 virtual std::string realname() const = 0; | |
| 60 virtual std::string type() const { return ""; } | |
| 61 virtual const value_renderer* get_value_renderer() const { return nullptr; } | |
| 62 virtual std::string extra_modifiers() const { return ""; } | |
| 63 virtual std::string crypt_value(const std::string&) const { return ""; } | |
| 64 virtual std::string decrypt_value(const std::string&) const { return ""; } | |
| 65 virtual Column* clone() const { return nullptr; } | |
| 66 }; | |
| 67 | |
| 68 class DescAsColumn : public NotAColumn | |
| 69 { | |
| 70 public: | |
| 71 typedef DescAsColumn type; | |
| 72 virtual std::string name() const { return "DESC"; } | |
| 73 virtual std::string realname() const { return "DESC"; } | |
| 74 }; | |
| 75 | |
| 76 class AscAsColumn : public NotAColumn | |
| 77 { | |
| 78 public: | |
| 79 typedef AscAsColumn type; | |
| 80 virtual std::string name() const { return "ASC"; } | |
| 81 virtual std::string realname() const { return "ASC"; } | |
| 82 }; | |
| 83 | |
| 84 #define DESC ,DescAsColumn() | |
| 85 #define ASC ,AscAsColumn() | |
| 86 | |
| 87 class BasicTable | |
| 88 { | |
| 89 public: | |
| 90 virtual std::string name() const = 0; | |
| 91 virtual bool is_crypted() const = 0; | |
| 92 virtual ~BasicTable() = default; | |
| 93 }; | |
| 94 | |
| 95 struct Functor | |
| 96 { | |
| 97 Functor(std::string& rstr) : s(rstr) {} | |
| 98 std::string& s; | |
| 99 | |
| 100 template<typename T> | |
| 101 void operator()(T& t) | |
| 102 { | |
| 103 std::string g = unafrog::utils::to_string(t); | |
| 104 this->s = g; | |
| 105 } | |
| 106 }; | |
| 107 | |
| 108 struct GetNameFunctor | |
| 109 { | |
| 110 GetNameFunctor(std::string& rstr) : s(rstr) {} | |
| 111 std::string& s; | |
| 112 | |
| 113 template<typename T> | |
| 114 void operator()(T& t) | |
| 115 { | |
| 116 std::string g = t.name(); | |
| 117 this->s = g; | |
| 118 } | |
| 119 }; | |
| 120 | |
| 121 | |
| 122 static const char* insert_into = "INSERT OR IGNORE INTO "; | |
| 123 | |
| 124 // columnset stuff for insert operations | |
| 125 class Columnset | |
| 126 { | |
| 127 size_t colcount; | |
| 128 std::vector<std::string> colnames; | |
| 129 std::vector<const Column*> cols; | |
| 130 std::vector<const Column*> mcols; | |
| 131 | |
| 132 std::vector<const value_renderer*> valrends; | |
| 133 const BasicTable& t; | |
| 134 mutable std::string values_s; | |
| 135 mutable std::string s; | |
| 136 | |
| 137 public: | |
| 138 template<class ...Cs> | |
| 139 Columnset(const BasicTable& bt, Cs&... inputs) : colcount(sizeof...(Cs)), cols{&inputs...}, t(bt), values_s(""), | |
| 140 s(insert_into + t.name() + "(") | |
| 141 { | |
| 142 for (auto c : cols) | |
| 143 { | |
| 144 colnames.push_back(c->name()); | |
| 145 valrends.push_back(c->get_value_renderer()); | |
| 146 mcols.push_back(c->clone()); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 virtual ~Columnset() | |
| 151 { | |
| 152 for (auto c : mcols) | |
| 153 { | |
| 154 delete c; | |
| 155 } | |
| 156 for (auto c : valrends) | |
| 157 { | |
| 158 delete c; | |
| 159 } | |
| 160 } | |
| 161 | |
| 162 template <class ...Vals> | |
| 163 std::string insert(const char* c, Vals... v) | |
| 164 { | |
| 165 return std::string(c), + valset(v...); | |
| 166 } | |
| 167 | |
| 168 template <class ...Vals> | |
| 169 std::string insert(Vals... v) const | |
| 170 { | |
| 171 auto r = valset(v...); | |
| 172 for(size_t i=0; i<colcount; i++) | |
| 173 { | |
| 174 std::string cn = colnames.at(i); | |
| 175 s += cn.substr(cn.find('.') + 1); | |
| 176 | |
| 177 // the value from the template arguments, stored as a tuple. | |
| 178 std::string returned; | |
| 179 Functor a(returned); | |
| 180 for_index(i, r, a); | |
| 181 std::string crypted = mcols.at(i)->crypt_value(returned); | |
| 182 values_s += valrends.at(i)->render(crypted); | |
| 183 if(i < cols.size() - 1) | |
| 184 { | |
| 185 s+= ", "; | |
| 186 values_s += ", "; | |
| 187 } | |
| 188 } | |
| 189 s += ") VALUES (" + values_s + ")"; | |
| 190 return s; | |
| 191 } | |
| 192 | |
| 193 std::string prepare_insert() const | |
| 194 { | |
| 195 std::string s = std::string(insert_into) + t.name() + "("; | |
| 196 std::string values_s = ""; | |
| 197 | |
| 198 for(size_t i=0; i<colcount; i++) | |
| 199 { | |
| 200 std::string cn = mcols[i]->name(); | |
| 201 s += cn.substr(cn.find('.') + 1); | |
| 202 values_s += ":v" + std::to_string(i + 1); | |
| 203 | |
| 204 if(i < cols.size() - 1) | |
| 205 { | |
| 206 s+= ", "; | |
| 207 values_s += ", "; | |
| 208 } | |
| 209 } | |
| 210 s += _O(") VALUES (") + values_s + ")"; | |
| 211 return s; | |
| 212 } | |
| 213 | |
| 214 }; | |
| 215 | |
| 216 /** | |
| 217 * Class representing a Table | |
| 218 */ | |
| 219 class Table : public BasicTable | |
| 220 { | |
| 221 mutable std::vector<std::string> foreign_keys; | |
| 222 std::vector<std::string> inited_foreign_keys; | |
| 223 std::vector<const Column*> columns; | |
| 224 std::string resolve_foreign_key(const std::string& s) const; | |
| 225 | |
| 226 protected: | |
| 227 bool init_foreign_key(const std::string& s); | |
| 228 | |
| 229 public: | |
| 230 virtual std::string verify() const; | |
| 231 virtual std::string create() const; | |
| 232 | |
| 233 virtual std::string name() const = 0; | |
| 234 virtual std::string realname() const = 0; | |
| 235 virtual bool is_crypted() const = 0; | |
| 236 | |
| 237 void addColumn(const Column* c) {columns.push_back(c);} | |
| 238 }; | |
| 239 | |
| 240 class Condition | |
| 241 { | |
| 242 public: | |
| 243 Condition(const std::string& s); | |
| 244 std::string cond() const; | |
| 245 private: | |
| 246 std::string cstr; | |
| 247 }; | |
| 248 | |
| 249 std::string operator && (const Condition& c1, const Condition& c2); | |
| 250 std::string operator || (const Condition& c1, const Condition& c2); | |
| 251 typedef std::string (*PT)(const Condition& c1, const Condition& c2); | |
| 252 | |
| 253 #define AND && | |
| 254 #define OR || | |
| 255 | |
| 256 template<typename TF> | |
| 257 std::string write_debug_output( TF const& f) { | |
| 258 std::stringstream ss; | |
| 259 ss << f.get_modifier(); | |
| 260 return ss.str(); | |
| 261 } | |
| 262 | |
| 263 struct modifier_retriever { | |
| 264 template<typename TF, typename ... TR> | |
| 265 std::string write( TF const& f, TR const& ... rest ) { | |
| 266 std::string full = write_debug_output( f ); | |
| 267 full += " "; | |
| 268 full += write( rest... ); | |
| 269 return full; | |
| 270 } | |
| 271 template<typename TF> | |
| 272 std::string write( TF const& f ) { | |
| 273 return write_debug_output( f ); | |
| 274 } | |
| 275 std::string write() { | |
| 276 return ""; | |
| 277 } | |
| 278 }; | |
| 279 | |
| 280 namespace cppdb | |
| 281 { | |
| 282 std::string crypt_db_name(const std::string& in); | |
| 283 std::string crypt_db_value(const std::string& in, bool do_crypt); | |
| 284 std::string decrypt_db_value(const std::string& in, bool do_decrypt); | |
| 285 unsigned long crypt_number(unsigned long in, bool do_crypt); | |
| 286 unsigned long decrypt_number(unsigned long in, bool do_crypt); | |
| 287 } | |
| 288 | |
| 289 #define TABLE_WRAPPER(Name,Crypt) namespace { \ | |
| 290 class Table##Name : public Table \ | |
| 291 { \ | |
| 292 mutable std::string crypted_name = ""; \ | |
| 293 public: \ | |
| 294 static std::string tablename; \ | |
| 295 Table##Name() {} \ | |
| 296 bool is_crypted() const {return Crypt;} \ | |
| 297 template<class ...Cs> \ | |
| 298 const Columnset operator() (Cs... cols) const \ | |
| 299 { return Columnset(*this, cols...);} \ | |
| 300 virtual std::string name() const \ | |
| 301 { \ | |
| 302 if(Crypt) \ | |
| 303 { \ | |
| 304 if(crypted_name.empty()) \ | |
| 305 crypted_name = cppdb::crypt_db_name(tablename); \ | |
| 306 return crypted_name; \ | |
| 307 } \ | |
| 308 else return tablename; \ | |
| 309 } \ | |
| 310 virtual std::string realname() const {return tablename; } | |
| 311 | |
| 312 #define TABLE(Name) TABLE_WRAPPER(Name,0) | |
| 313 #define CRYP_TABLE(Name) TABLE_WRAPPER(Name,1) | |
| 314 | |
| 315 // Will create the actual "Name" object of type Table##Name | |
| 316 #define ENDTABLE(Name) }; \ | |
| 317 std::string Table##Name::tablename = #Name; \ | |
| 318 const Table##Name& Name = Table##Name(); \ | |
| 319 bool MACRO_CONCAT(reg_tab_, Name) = cppdb_warehouse::instance().add_table(&Name); \ | |
| 320 } | |
| 321 | |
| 322 #define DEF_OPERATOR(OP,sqlop,Type) \ | |
| 323 Condition operator OP (const Type::type& t) const \ | |
| 324 { return Condition( "(" + name() + #sqlop + unafrog::utils::to_string(t) + ")"); } \ | |
| 325 Condition operator OP (const Column& t) const \ | |
| 326 { return Condition( "(" + name() + #sqlop + t.name() + ")"); } \ | |
| 327 | |
| 328 | |
| 329 #define COLUMN_WRAPPER(Name, Type, Crypt, ...) \ | |
| 330 class Column##Name : public BasicColumn \ | |
| 331 { \ | |
| 332 Table& parent; \ | |
| 333 mutable std::string crypted_name = ""; \ | |
| 334 std::string extra = modifier_retriever().write(__VA_ARGS__); \ | |
| 335 public: \ | |
| 336 Column##Name (Table& p) : parent(p) {p.addColumn(this);} \ | |
| 337 virtual std::string name() const \ | |
| 338 { \ | |
| 339 if (Crypt || parent.is_crypted()) \ | |
| 340 { \ | |
| 341 if(crypted_name.empty()) \ | |
| 342 { \ | |
| 343 crypted_name = parent.name() + "." + cppdb::crypt_db_name(#Name); \ | |
| 344 } \ | |
| 345 return crypted_name; \ | |
| 346 } \ | |
| 347 else return parent.name() + "." + #Name; \ | |
| 348 } \ | |
| 349 virtual std::string realname() const { return #Name; } \ | |
| 350 DEF_OPERATOR(==, =, Type) \ | |
| 351 Condition operator == (const std::string& t) const \ | |
| 352 { return Condition( "(" + name() + " = '" + t + "')"); } \ | |
| 353 DEF_OPERATOR(!=, <>, Type) \ | |
| 354 DEF_OPERATOR(<=, <=, Type) \ | |
| 355 DEF_OPERATOR(>=, >=, Type) \ | |
| 356 DEF_OPERATOR(<, <, Type) \ | |
| 357 DEF_OPERATOR(>, >, Type) \ | |
| 358 std::string type() const { return Type().get_type(); } \ | |
| 359 std::string extra_modifiers() const { return extra; } \ | |
| 360 const value_renderer* get_value_renderer() const { return new Type(); } \ | |
| 361 std::string crypt_value(const std::string& value) const \ | |
| 362 { \ | |
| 363 return Type(value).crypted(Crypt || parent.is_crypted()); \ | |
| 364 } \ | |
| 365 std::string crypt_value(const Type::type& value) const \ | |
| 366 { \ | |
| 367 return Type(value).crypted(Crypt || parent.is_crypted()); \ | |
| 368 } \ | |
| 369 std::string decrypt_value(const std::string& value) const \ | |
| 370 { \ | |
| 371 return Type(value).decrypted(Crypt || parent.is_crypted()).value(); \ | |
| 372 } \ | |
| 373 Column* clone() const { Column* c = new Column##Name(parent); dynamic_cast<Column##Name*>(c)->crypted_name = crypted_name; dynamic_cast<Column##Name*>(c)->extra = extra; return c;}\ | |
| 374 }; \ | |
| 375 Column##Name Name = Column##Name(*this); \ | |
| 376 bool MACRO_CONCAT(reg_col_, Name) = cppdb_warehouse::instance().add_column(&Name) | |
| 377 | |
| 378 | |
| 379 #define COLUMN(Name, Type, ...) COLUMN_WRAPPER(Name, Type, 0, __VA_ARGS__) | |
| 380 #define CRYP_COLUMN(Name, Type, ...) COLUMN_WRAPPER(Name, Type, 1, __VA_ARGS__) | |
| 381 | |
| 382 // Foreign Key stuff | |
| 383 #define FOREIGN_KEY(X) bool MACRO_CONCAT(g, __COUNTER__ ) = init_foreign_key(std::string(#X)) | |
| 384 | |
| 385 // Order by | |
| 386 | |
| 387 template<typename T, typename U> | |
| 388 struct is_same : std::false_type { }; | |
| 389 | |
| 390 template<typename T> | |
| 391 struct is_same<T, T> : std::true_type { }; | |
| 392 | |
| 393 template<typename T, typename U> | |
| 394 constexpr bool eqTypes() { return is_same<T, U>::value; } | |
| 395 | |
| 396 std::string orderby_helper(const Column& c); | |
| 397 | |
| 398 template <class... args> | |
| 399 std::string orderby_helper(args... a) | |
| 400 { | |
| 401 | |
| 402 std::size_t cnt = sizeof...(args); | |
| 403 auto r = std::tuple<args...>(a...); | |
| 404 std::vector<std::string> columns; | |
| 405 | |
| 406 for(std::size_t i=0; i<cnt; i++) | |
| 407 { | |
| 408 std::string returned; | |
| 409 GetNameFunctor a(returned); | |
| 410 for_index(i, r, a); | |
| 411 columns.push_back(returned); | |
| 412 } | |
| 413 std::string result = ""; | |
| 414 for(size_t i = 0; i<columns.size(); i++) | |
| 415 { | |
| 416 result += columns.at(i); | |
| 417 if(i < columns.size() - 1) | |
| 418 { | |
| 419 if(columns.at(i + 1) != "ASC" && columns.at(i + 1) != "DESC") | |
| 420 { | |
| 421 result += ", "; | |
| 422 } | |
| 423 else | |
| 424 { | |
| 425 result += " "; | |
| 426 } | |
| 427 } | |
| 428 } | |
| 429 return result; | |
| 430 } | |
| 431 | |
| 432 template <class... all> | |
| 433 std::string ORDER_BY(all... a) | |
| 434 { | |
| 435 std::string s = " ORDER BY "; | |
| 436 std::string g = orderby_helper(a...); | |
| 437 return s + g; | |
| 438 } | |
| 439 | |
| 440 // Where | |
| 441 | |
| 442 std::string where_helper(const Condition& c); | |
| 443 | |
| 444 template <class C = Condition, class... args> | |
| 445 std::string where_helper(const Condition& c, args... a) | |
| 446 { | |
| 447 std::string s = c.cond(); | |
| 448 s += from(a...); | |
| 449 return s; | |
| 450 } | |
| 451 | |
| 452 template <class... all> | |
| 453 std::string WHERE(all... a) | |
| 454 { | |
| 455 std::string s = "WHERE "; | |
| 456 std::string g = where_helper(a...); | |
| 457 return s + g; | |
| 458 } | |
| 459 | |
| 460 // From | |
| 461 | |
| 462 std::string from_helper(const Table& t); | |
| 463 | |
| 464 template <class T = Table, class... args> | |
| 465 std::string from_helper(const Table& t, args... a) | |
| 466 { | |
| 467 std::string s = t.name() + ", "; | |
| 468 s += from_helper(a...); | |
| 469 return s; | |
| 470 } | |
| 471 | |
| 472 template <class... all> | |
| 473 std::string FROM(all... a) | |
| 474 { | |
| 475 std::string s = "FROM "; | |
| 476 std::string g = from_helper(a...); | |
| 477 return s + g + " "; | |
| 478 } | |
| 479 | |
| 480 // Select | |
| 481 | |
| 482 std::string select_helper(const Column& c); | |
| 483 | |
| 484 template <class C = Column, class... args> | |
| 485 std::string select_helper(const Column& c, args... a) | |
| 486 { | |
| 487 std::string s = c.name() + ", "; | |
| 488 s += select_helper(a...); | |
| 489 return s; | |
| 490 } | |
| 491 | |
| 492 | |
| 493 template <class... all> | |
| 494 std::string SELECT(all... a) | |
| 495 { | |
| 496 std::string s = "SELECT "; | |
| 497 std::string g = select_helper(a...); | |
| 498 return s + g + " "; | |
| 499 } | |
| 500 | |
| 501 // Delete | |
| 502 | |
| 503 #define DELETE "DELETE " | |
| 504 | |
| 505 // Update | |
| 506 | |
| 507 std::string UPDATE(const Table& tab); | |
| 508 | |
| 509 std::string set_helper(int total_size, const Column& c); | |
| 510 | |
| 511 template <class C = Column, class... args> | |
| 512 std::string set_helper(std::size_t total_size, const Column& c, args... a) | |
| 513 { | |
| 514 std::string s = c.realname() + "=:v"; | |
| 515 std::stringstream ss; | |
| 516 ss << total_size - sizeof...(a); | |
| 517 s += ss.str() + ", "; | |
| 518 s += set_helper(total_size, a...); | |
| 519 return s; | |
| 520 } | |
| 521 | |
| 522 template <class... all> | |
| 523 std::string SET(all... a) | |
| 524 { | |
| 525 std::string s = " SET "; | |
| 526 std::string g = set_helper(sizeof...(a), a...); | |
| 527 return s + g ; | |
| 528 } | |
| 529 | |
| 530 // varchar support | |
| 531 template<size_t SIZE> class varchar : public value_renderer | |
| 532 { | |
| 533 public: | |
| 534 // this has to be "const char*" otherwise overloading upon const std::string& is not possible in Column classes | |
| 535 typedef const char* type; | |
| 536 | |
| 537 varchar() : s(SIZE) {} | |
| 538 varchar(const std::string& v) : s(SIZE), mvalue(v) {} | |
| 539 operator std::string () const | |
| 540 { | |
| 541 return _O("VARCHAR(") + std::to_string(s) + ")"; | |
| 542 } | |
| 543 | |
| 544 std::string get_type() const | |
| 545 { | |
| 546 return operator std::string(); | |
| 547 } | |
| 548 | |
| 549 virtual std::string render(const std::string& t) const {return "\"" + t + "\"" ; } | |
| 550 | |
| 551 virtual std::string crypted(bool crypt) {return cppdb::crypt_db_value(mvalue, crypt); } | |
| 552 virtual value_renderer& decrypted(bool crypt) { mvalue = cppdb::decrypt_db_value(mvalue, crypt); return *this;} | |
| 553 std::string value() const {return mvalue; } | |
| 554 private: | |
| 555 size_t s; | |
| 556 std::string mvalue = ""; | |
| 557 }; | |
| 558 | |
| 559 template <size_t SIZE> | |
| 560 std::basic_ostream<char>& operator << (std::basic_ostream<char>& os, varchar<SIZE> vc) | |
| 561 { | |
| 562 os << vc.operator std::string(); | |
| 563 return os; | |
| 564 } | |
| 565 | |
| 566 #define VARCHAR(S) varchar<S> | |
| 567 | |
| 568 // text support | |
| 569 class text: public value_renderer | |
| 570 { | |
| 571 public: | |
| 572 // this has to be "const char*" otherwise overloading upon const std::string& is not possible in Column classes | |
| 573 typedef const char* type; | |
| 574 | |
| 575 text() = default; | |
| 576 text(const std::string& v) : mvalue(v) {} | |
| 577 operator std::string () const | |
| 578 { | |
| 579 return _O("TEXT"); | |
| 580 } | |
| 581 | |
| 582 std::string get_type() const | |
| 583 { | |
| 584 return operator std::string(); | |
| 585 } | |
| 586 | |
| 587 virtual std::string render(const std::string& t) const {return "\"" + t + "\"" ; } | |
| 588 | |
| 589 virtual std::string crypted(bool crypt) {return cppdb::crypt_db_value(mvalue, crypt); } | |
| 590 virtual value_renderer& decrypted(bool crypt) { mvalue = cppdb::decrypt_db_value(mvalue, crypt); return *this;} | |
| 591 std::string value() const {return mvalue; } | |
| 592 private: | |
| 593 std::string mvalue = ""; | |
| 594 }; | |
| 595 std::basic_ostream<char>& operator << (std::basic_ostream<char>& os, const text& tx); | |
| 596 | |
| 597 #define TEXT text | |
| 598 | |
| 599 // other types support | |
| 600 template <class T> class simple_type : public value_renderer | |
| 601 { | |
| 602 public: | |
| 603 typedef T type; | |
| 604 simple_type() = default; | |
| 605 simple_type(T t) : mt(t) {} | |
| 606 private: | |
| 607 T mt; | |
| 608 }; | |
| 609 | |
| 610 template <> class simple_type<time_t> : public value_renderer | |
| 611 { | |
| 612 public: | |
| 613 typedef int type; | |
| 614 simple_type() = default; | |
| 615 simple_type(time_t t) : mt(t) {} | |
| 616 simple_type(const std::string& sv) : mt(stol(sv)) {} | |
| 617 std::string get_type() const {return _O("TIMESTAMP"); } | |
| 618 virtual std::string crypted(bool crypt) {return std::to_string(cppdb::crypt_number(mt, crypt));} | |
| 619 virtual value_renderer& decrypted(bool crypt) { mt = cppdb::decrypt_number(mt, crypt); return *this; } | |
| 620 std::string value() const {return std::to_string(mt); } | |
| 621 private: | |
| 622 time_t mt = 0; | |
| 623 }; | |
| 624 | |
| 625 template <> class simple_type<int> : public value_renderer | |
| 626 { | |
| 627 public: | |
| 628 typedef int type; | |
| 629 simple_type() = default; | |
| 630 simple_type(int t) : mt(t) {} | |
| 631 simple_type(const std::string& sv) : mt(stoi(sv)) {} | |
| 632 std::string get_type() const {return _O("INTEGER"); } | |
| 633 virtual std::string crypted(bool crypt) {return std::to_string(cppdb::crypt_number(mt, crypt));} | |
| 634 virtual value_renderer& decrypted(bool crypt) { mt = static_cast<int>(cppdb::decrypt_number(mt, crypt)); return *this; } | |
| 635 std::string value() const {return std::to_string(mt); } | |
| 636 private: | |
| 637 int mt = 0; | |
| 638 }; | |
| 639 | |
| 640 #define INTEGER simple_type<int> | |
| 641 #define TIMESTAMP simple_type<time_t> | |
| 642 | |
| 643 struct primary_key { const std::string modifier() {return _O("PRIMARY KEY"); } }; | |
| 644 struct not_null { const std::string modifier() {return _O("NOT NULL"); } }; | |
| 645 | |
| 646 template<class D> | |
| 647 struct defaults | |
| 648 { | |
| 649 defaults(const D& d) : md(d) {} | |
| 650 std::string get_modifier() const | |
| 651 { | |
| 652 std::string res = _O("DEFAULT "); | |
| 653 std::stringstream ss; ss << md ; return res + ss.str(); | |
| 654 } | |
| 655 private: | |
| 656 D md; | |
| 657 }; | |
| 658 | |
| 659 template <class T> class modifier_templ | |
| 660 { | |
| 661 public: | |
| 662 modifier_templ(){} | |
| 663 std::string get_modifier() const {return T().modifier();} | |
| 664 }; | |
| 665 | |
| 666 static const modifier_templ<primary_key> pk; | |
| 667 static const modifier_templ<not_null> nn; | |
| 668 | |
| 669 #define PRIMARY_KEY pk | |
| 670 #define NOT_NULL nn | |
| 671 #define CURRENT_TIMESTAMP _O("CURRENT_TIMESTAMP") | |
| 672 #define DEFAULT(X) defaults<decltype(X)>(X) | |
| 673 | |
| 674 /* The actual warehouse keeping all the tables, columns and other elements */ | |
| 675 class cppdb_warehouse | |
| 676 { | |
| 677 public: | |
| 678 static cppdb_warehouse& instance(); | |
| 679 bool add_column(const Column* c); | |
| 680 bool add_table(const Table* t); | |
| 681 const Table* table(const std::string& tabname); | |
| 682 const Column* column(const std::string& colname); | |
| 683 private: | |
| 684 std::vector<const Column*> columns; | |
| 685 std::vector<const Table*> tables; | |
| 686 }; | |
| 687 | |
| 688 #endif // CPPDB |
