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