ferencd@0: #ifndef CPPDB_H ferencd@0: #define CPPDB_H ferencd@0: ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: ferencd@0: #define _O(x) x ferencd@0: ferencd@0: // helper macros ferencd@0: #define CONCAT_IMPL( x, y ) x##y ferencd@0: #define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y ) ferencd@0: ferencd@0: // basic value retrieval for various column types ferencd@0: struct value_renderer ferencd@0: { ferencd@0: value_renderer() = default; ferencd@0: virtual ~value_renderer() = default; ferencd@0: virtual std::string render(const std::string& t) const { return t; } ferencd@0: ferencd@0: virtual std::string value() const = 0; ferencd@0: virtual std::string crypted(bool) = 0; ferencd@0: virtual value_renderer& decrypted(bool) = 0; ferencd@0: ferencd@0: }; ferencd@0: ferencd@0: /** ferencd@0: * Class representing a column ferencd@0: */ ferencd@0: class Column ferencd@0: { ferencd@0: public: ferencd@0: virtual ~Column() = default; ferencd@0: virtual std::string name() const = 0; ferencd@0: virtual std::string realname() const = 0; ferencd@0: virtual std::string type() const = 0; ferencd@0: virtual const value_renderer* get_value_renderer() const = 0; ferencd@0: virtual std::string extra_modifiers() const = 0; ferencd@0: virtual std::string crypt_value(const std::string&) const = 0; ferencd@0: virtual std::string decrypt_value(const std::string&) const = 0; ferencd@0: virtual Column* clone() const = 0; ferencd@0: }; ferencd@0: ferencd@0: class BasicColumn : public Column ferencd@0: { ferencd@0: public: ferencd@0: virtual std::string name() const { return "" ;} ferencd@0: virtual std::string type() const { return "" ;} ferencd@0: virtual std::string extra_modifiers() const { return "";} ferencd@0: }; ferencd@0: ferencd@0: class NotAColumn : public Column ferencd@0: { ferencd@0: public: ferencd@0: virtual std::string name() const = 0; ferencd@0: virtual std::string realname() const = 0; ferencd@0: virtual std::string type() const { return ""; } ferencd@0: virtual const value_renderer* get_value_renderer() const { return nullptr; } ferencd@0: virtual std::string extra_modifiers() const { return ""; } ferencd@0: virtual std::string crypt_value(const std::string&) const { return ""; } ferencd@0: virtual std::string decrypt_value(const std::string&) const { return ""; } ferencd@0: virtual Column* clone() const { return nullptr; } ferencd@0: }; ferencd@0: ferencd@0: class DescAsColumn : public NotAColumn ferencd@0: { ferencd@0: public: ferencd@0: typedef DescAsColumn type; ferencd@0: virtual std::string name() const { return "DESC"; } ferencd@0: virtual std::string realname() const { return "DESC"; } ferencd@0: }; ferencd@0: ferencd@0: class AscAsColumn : public NotAColumn ferencd@0: { ferencd@0: public: ferencd@0: typedef AscAsColumn type; ferencd@0: virtual std::string name() const { return "ASC"; } ferencd@0: virtual std::string realname() const { return "ASC"; } ferencd@0: }; ferencd@0: ferencd@0: #define DESC ,DescAsColumn() ferencd@0: #define ASC ,AscAsColumn() ferencd@0: ferencd@0: class BasicTable ferencd@0: { ferencd@0: public: ferencd@0: virtual std::string name() const = 0; ferencd@0: virtual bool is_crypted() const = 0; ferencd@0: virtual ~BasicTable() = default; ferencd@0: }; ferencd@0: ferencd@0: struct Functor ferencd@0: { ferencd@0: Functor(std::string& rstr) : s(rstr) {} ferencd@0: std::string& s; ferencd@0: ferencd@0: template ferencd@0: void operator()(T& t) ferencd@0: { ferencd@0: std::string g = unafrog::utils::to_string(t); ferencd@0: this->s = g; ferencd@0: } ferencd@0: }; ferencd@0: ferencd@0: struct GetNameFunctor ferencd@0: { ferencd@0: GetNameFunctor(std::string& rstr) : s(rstr) {} ferencd@0: std::string& s; ferencd@0: ferencd@0: template ferencd@0: void operator()(T& t) ferencd@0: { ferencd@0: std::string g = t.name(); ferencd@0: this->s = g; ferencd@0: } ferencd@0: }; ferencd@0: ferencd@0: ferencd@0: static const char* insert_into = "INSERT OR IGNORE INTO "; ferencd@0: ferencd@0: // columnset stuff for insert operations ferencd@0: class Columnset ferencd@0: { ferencd@0: size_t colcount; ferencd@0: std::vector colnames; ferencd@0: std::vector cols; ferencd@0: std::vector mcols; ferencd@0: ferencd@0: std::vector valrends; ferencd@0: const BasicTable& t; ferencd@0: mutable std::string values_s; ferencd@0: mutable std::string s; ferencd@0: ferencd@0: public: ferencd@0: template ferencd@0: Columnset(const BasicTable& bt, Cs&... inputs) : colcount(sizeof...(Cs)), cols{&inputs...}, t(bt), values_s(""), ferencd@0: s(insert_into + t.name() + "(") ferencd@0: { ferencd@0: for (auto c : cols) ferencd@0: { ferencd@0: colnames.push_back(c->name()); ferencd@0: valrends.push_back(c->get_value_renderer()); ferencd@0: mcols.push_back(c->clone()); ferencd@0: } ferencd@0: } ferencd@0: ferencd@0: virtual ~Columnset() ferencd@0: { ferencd@0: for (auto c : mcols) ferencd@0: { ferencd@0: delete c; ferencd@0: } ferencd@0: for (auto c : valrends) ferencd@0: { ferencd@0: delete c; ferencd@0: } ferencd@0: } ferencd@0: ferencd@0: template ferencd@0: std::string insert(const char* c, Vals... v) ferencd@0: { ferencd@0: return std::string(c), + valset(v...); ferencd@0: } ferencd@0: ferencd@0: template ferencd@0: std::string insert(Vals... v) const ferencd@0: { ferencd@0: auto r = valset(v...); ferencd@0: for(size_t i=0; icrypt_value(returned); ferencd@0: values_s += valrends.at(i)->render(crypted); ferencd@0: if(i < cols.size() - 1) ferencd@0: { ferencd@0: s+= ", "; ferencd@0: values_s += ", "; ferencd@0: } ferencd@0: } ferencd@0: s += ") VALUES (" + values_s + ")"; ferencd@0: return s; ferencd@0: } ferencd@0: ferencd@0: std::string prepare_insert() const ferencd@0: { ferencd@0: std::string s = std::string(insert_into) + t.name() + "("; ferencd@0: std::string values_s = ""; ferencd@0: ferencd@0: for(size_t i=0; iname(); ferencd@0: s += cn.substr(cn.find('.') + 1); ferencd@0: values_s += ":v" + std::to_string(i + 1); ferencd@0: ferencd@0: if(i < cols.size() - 1) ferencd@0: { ferencd@0: s+= ", "; ferencd@0: values_s += ", "; ferencd@0: } ferencd@0: } ferencd@0: s += _O(") VALUES (") + values_s + ")"; ferencd@0: return s; ferencd@0: } ferencd@0: ferencd@0: }; ferencd@0: ferencd@0: /** ferencd@0: * Class representing a Table ferencd@0: */ ferencd@0: class Table : public BasicTable ferencd@0: { ferencd@0: mutable std::vector foreign_keys; ferencd@0: std::vector inited_foreign_keys; ferencd@0: std::vector columns; ferencd@0: std::string resolve_foreign_key(const std::string& s) const; ferencd@0: ferencd@0: protected: ferencd@0: bool init_foreign_key(const std::string& s); ferencd@0: ferencd@0: public: ferencd@0: virtual std::string verify() const; ferencd@0: virtual std::string create() const; ferencd@0: ferencd@0: virtual std::string name() const = 0; ferencd@0: virtual std::string realname() const = 0; ferencd@0: virtual bool is_crypted() const = 0; ferencd@0: ferencd@0: void addColumn(const Column* c) {columns.push_back(c);} ferencd@0: }; ferencd@0: ferencd@0: class Condition ferencd@0: { ferencd@0: public: ferencd@0: Condition(const std::string& s); ferencd@0: std::string cond() const; ferencd@0: private: ferencd@0: std::string cstr; ferencd@0: }; ferencd@0: ferencd@0: std::string operator && (const Condition& c1, const Condition& c2); ferencd@0: std::string operator || (const Condition& c1, const Condition& c2); ferencd@0: typedef std::string (*PT)(const Condition& c1, const Condition& c2); ferencd@0: ferencd@0: #define AND && ferencd@0: #define OR || ferencd@0: ferencd@0: template ferencd@0: std::string write_debug_output( TF const& f) { ferencd@0: std::stringstream ss; ferencd@0: ss << f.get_modifier(); ferencd@0: return ss.str(); ferencd@0: } ferencd@0: ferencd@0: struct modifier_retriever { ferencd@0: template ferencd@0: std::string write( TF const& f, TR const& ... rest ) { ferencd@0: std::string full = write_debug_output( f ); ferencd@0: full += " "; ferencd@0: full += write( rest... ); ferencd@0: return full; ferencd@0: } ferencd@0: template ferencd@0: std::string write( TF const& f ) { ferencd@0: return write_debug_output( f ); ferencd@0: } ferencd@0: std::string write() { ferencd@0: return ""; ferencd@0: } ferencd@0: }; ferencd@0: ferencd@0: namespace cppdb ferencd@0: { ferencd@0: std::string crypt_db_name(const std::string& in); ferencd@0: std::string crypt_db_value(const std::string& in, bool do_crypt); ferencd@0: std::string decrypt_db_value(const std::string& in, bool do_decrypt); ferencd@0: unsigned long crypt_number(unsigned long in, bool do_crypt); ferencd@0: unsigned long decrypt_number(unsigned long in, bool do_crypt); ferencd@0: } ferencd@0: ferencd@0: #define TABLE_WRAPPER(Name,Crypt) namespace { \ ferencd@0: class Table##Name : public Table \ ferencd@0: { \ ferencd@0: mutable std::string crypted_name = ""; \ ferencd@0: public: \ ferencd@0: static std::string tablename; \ ferencd@0: Table##Name() {} \ ferencd@0: bool is_crypted() const {return Crypt;} \ ferencd@0: template \ ferencd@0: const Columnset operator() (Cs... cols) const \ ferencd@0: { return Columnset(*this, cols...);} \ ferencd@0: virtual std::string name() const \ ferencd@0: { \ ferencd@0: if(Crypt) \ ferencd@0: { \ ferencd@0: if(crypted_name.empty()) \ ferencd@0: crypted_name = cppdb::crypt_db_name(tablename); \ ferencd@0: return crypted_name; \ ferencd@0: } \ ferencd@0: else return tablename; \ ferencd@0: } \ ferencd@0: virtual std::string realname() const {return tablename; } ferencd@0: ferencd@0: #define TABLE(Name) TABLE_WRAPPER(Name,0) ferencd@0: #define CRYP_TABLE(Name) TABLE_WRAPPER(Name,1) ferencd@0: ferencd@0: // Will create the actual "Name" object of type Table##Name ferencd@0: #define ENDTABLE(Name) }; \ ferencd@0: std::string Table##Name::tablename = #Name; \ ferencd@0: const Table##Name& Name = Table##Name(); \ ferencd@0: bool MACRO_CONCAT(reg_tab_, Name) = cppdb_warehouse::instance().add_table(&Name); \ ferencd@0: } ferencd@0: ferencd@0: #define DEF_OPERATOR(OP,sqlop,Type) \ ferencd@0: Condition operator OP (const Type::type& t) const \ ferencd@0: { return Condition( "(" + name() + #sqlop + unafrog::utils::to_string(t) + ")"); } \ ferencd@0: Condition operator OP (const Column& t) const \ ferencd@0: { return Condition( "(" + name() + #sqlop + t.name() + ")"); } \ ferencd@0: ferencd@0: ferencd@0: #define COLUMN_WRAPPER(Name, Type, Crypt, ...) \ ferencd@0: class Column##Name : public BasicColumn \ ferencd@0: { \ ferencd@0: Table& parent; \ ferencd@0: mutable std::string crypted_name = ""; \ ferencd@0: std::string extra = modifier_retriever().write(__VA_ARGS__); \ ferencd@0: public: \ ferencd@0: Column##Name (Table& p) : parent(p) {p.addColumn(this);} \ ferencd@0: virtual std::string name() const \ ferencd@0: { \ ferencd@0: if (Crypt || parent.is_crypted()) \ ferencd@0: { \ ferencd@0: if(crypted_name.empty()) \ ferencd@0: { \ ferencd@0: crypted_name = parent.name() + "." + cppdb::crypt_db_name(#Name); \ ferencd@0: } \ ferencd@0: return crypted_name; \ ferencd@0: } \ ferencd@0: else return parent.name() + "." + #Name; \ ferencd@0: } \ ferencd@0: virtual std::string realname() const { return #Name; } \ ferencd@0: DEF_OPERATOR(==, =, Type) \ ferencd@0: Condition operator == (const std::string& t) const \ ferencd@0: { return Condition( "(" + name() + " = '" + t + "')"); } \ ferencd@0: DEF_OPERATOR(!=, <>, Type) \ ferencd@0: DEF_OPERATOR(<=, <=, Type) \ ferencd@0: DEF_OPERATOR(>=, >=, Type) \ ferencd@0: DEF_OPERATOR(<, <, Type) \ ferencd@0: DEF_OPERATOR(>, >, Type) \ ferencd@0: std::string type() const { return Type().get_type(); } \ ferencd@0: std::string extra_modifiers() const { return extra; } \ ferencd@0: const value_renderer* get_value_renderer() const { return new Type(); } \ ferencd@0: std::string crypt_value(const std::string& value) const \ ferencd@0: { \ ferencd@0: return Type(value).crypted(Crypt || parent.is_crypted()); \ ferencd@0: } \ ferencd@0: std::string crypt_value(const Type::type& value) const \ ferencd@0: { \ ferencd@0: return Type(value).crypted(Crypt || parent.is_crypted()); \ ferencd@0: } \ ferencd@0: std::string decrypt_value(const std::string& value) const \ ferencd@0: { \ ferencd@0: return Type(value).decrypted(Crypt || parent.is_crypted()).value(); \ ferencd@0: } \ ferencd@0: Column* clone() const { Column* c = new Column##Name(parent); dynamic_cast(c)->crypted_name = crypted_name; dynamic_cast(c)->extra = extra; return c;}\ ferencd@0: }; \ ferencd@0: Column##Name Name = Column##Name(*this); \ ferencd@0: bool MACRO_CONCAT(reg_col_, Name) = cppdb_warehouse::instance().add_column(&Name) ferencd@0: ferencd@0: ferencd@0: #define COLUMN(Name, Type, ...) COLUMN_WRAPPER(Name, Type, 0, __VA_ARGS__) ferencd@0: #define CRYP_COLUMN(Name, Type, ...) COLUMN_WRAPPER(Name, Type, 1, __VA_ARGS__) ferencd@0: ferencd@0: // Foreign Key stuff ferencd@0: #define FOREIGN_KEY(X) bool MACRO_CONCAT(g, __COUNTER__ ) = init_foreign_key(std::string(#X)) ferencd@0: ferencd@0: // Order by ferencd@0: ferencd@0: template ferencd@0: struct is_same : std::false_type { }; ferencd@0: ferencd@0: template ferencd@0: struct is_same : std::true_type { }; ferencd@0: ferencd@0: template ferencd@0: constexpr bool eqTypes() { return is_same::value; } ferencd@0: ferencd@0: std::string orderby_helper(const Column& c); ferencd@0: ferencd@0: template ferencd@0: std::string orderby_helper(args... a) ferencd@0: { ferencd@0: ferencd@0: std::size_t cnt = sizeof...(args); ferencd@0: auto r = std::tuple(a...); ferencd@0: std::vector columns; ferencd@0: ferencd@0: for(std::size_t i=0; i ferencd@0: std::string ORDER_BY(all... a) ferencd@0: { ferencd@0: std::string s = " ORDER BY "; ferencd@0: std::string g = orderby_helper(a...); ferencd@0: return s + g; ferencd@0: } ferencd@0: ferencd@0: // Where ferencd@0: ferencd@0: std::string where_helper(const Condition& c); ferencd@0: ferencd@0: template ferencd@0: std::string where_helper(const Condition& c, args... a) ferencd@0: { ferencd@0: std::string s = c.cond(); ferencd@0: s += from(a...); ferencd@0: return s; ferencd@0: } ferencd@0: ferencd@0: template ferencd@0: std::string WHERE(all... a) ferencd@0: { ferencd@0: std::string s = "WHERE "; ferencd@0: std::string g = where_helper(a...); ferencd@0: return s + g; ferencd@0: } ferencd@0: ferencd@0: // From ferencd@0: ferencd@0: std::string from_helper(const Table& t); ferencd@0: ferencd@0: template ferencd@0: std::string from_helper(const Table& t, args... a) ferencd@0: { ferencd@0: std::string s = t.name() + ", "; ferencd@0: s += from_helper(a...); ferencd@0: return s; ferencd@0: } ferencd@0: ferencd@0: template ferencd@0: std::string FROM(all... a) ferencd@0: { ferencd@0: std::string s = "FROM "; ferencd@0: std::string g = from_helper(a...); ferencd@0: return s + g + " "; ferencd@0: } ferencd@0: ferencd@0: // Select ferencd@0: ferencd@0: std::string select_helper(const Column& c); ferencd@0: ferencd@0: template ferencd@0: std::string select_helper(const Column& c, args... a) ferencd@0: { ferencd@0: std::string s = c.name() + ", "; ferencd@0: s += select_helper(a...); ferencd@0: return s; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: template ferencd@0: std::string SELECT(all... a) ferencd@0: { ferencd@0: std::string s = "SELECT "; ferencd@0: std::string g = select_helper(a...); ferencd@0: return s + g + " "; ferencd@0: } ferencd@0: ferencd@0: // Delete ferencd@0: ferencd@0: #define DELETE "DELETE " ferencd@0: ferencd@0: // Update ferencd@0: ferencd@0: std::string UPDATE(const Table& tab); ferencd@0: ferencd@0: std::string set_helper(int total_size, const Column& c); ferencd@0: ferencd@0: template ferencd@0: std::string set_helper(std::size_t total_size, const Column& c, args... a) ferencd@0: { ferencd@0: std::string s = c.realname() + "=:v"; ferencd@0: std::stringstream ss; ferencd@0: ss << total_size - sizeof...(a); ferencd@0: s += ss.str() + ", "; ferencd@0: s += set_helper(total_size, a...); ferencd@0: return s; ferencd@0: } ferencd@0: ferencd@0: template ferencd@0: std::string SET(all... a) ferencd@0: { ferencd@0: std::string s = " SET "; ferencd@0: std::string g = set_helper(sizeof...(a), a...); ferencd@0: return s + g ; ferencd@0: } ferencd@0: ferencd@0: // varchar support ferencd@0: template class varchar : public value_renderer ferencd@0: { ferencd@0: public: ferencd@0: // this has to be "const char*" otherwise overloading upon const std::string& is not possible in Column classes ferencd@0: typedef const char* type; ferencd@0: ferencd@0: varchar() : s(SIZE) {} ferencd@0: varchar(const std::string& v) : s(SIZE), mvalue(v) {} ferencd@0: operator std::string () const ferencd@0: { ferencd@0: return _O("VARCHAR(") + std::to_string(s) + ")"; ferencd@0: } ferencd@0: ferencd@0: std::string get_type() const ferencd@0: { ferencd@0: return operator std::string(); ferencd@0: } ferencd@0: ferencd@0: virtual std::string render(const std::string& t) const {return "\"" + t + "\"" ; } ferencd@0: ferencd@0: virtual std::string crypted(bool crypt) {return cppdb::crypt_db_value(mvalue, crypt); } ferencd@0: virtual value_renderer& decrypted(bool crypt) { mvalue = cppdb::decrypt_db_value(mvalue, crypt); return *this;} ferencd@0: std::string value() const {return mvalue; } ferencd@0: private: ferencd@0: size_t s; ferencd@0: std::string mvalue = ""; ferencd@0: }; ferencd@0: ferencd@0: template ferencd@0: std::basic_ostream& operator << (std::basic_ostream& os, varchar vc) ferencd@0: { ferencd@0: os << vc.operator std::string(); ferencd@0: return os; ferencd@0: } ferencd@0: ferencd@0: #define VARCHAR(S) varchar ferencd@0: ferencd@0: // text support ferencd@0: class text: public value_renderer ferencd@0: { ferencd@0: public: ferencd@0: // this has to be "const char*" otherwise overloading upon const std::string& is not possible in Column classes ferencd@0: typedef const char* type; ferencd@0: ferencd@0: text() = default; ferencd@0: text(const std::string& v) : mvalue(v) {} ferencd@0: operator std::string () const ferencd@0: { ferencd@0: return _O("TEXT"); ferencd@0: } ferencd@0: ferencd@0: std::string get_type() const ferencd@0: { ferencd@0: return operator std::string(); ferencd@0: } ferencd@0: ferencd@0: virtual std::string render(const std::string& t) const {return "\"" + t + "\"" ; } ferencd@0: ferencd@0: virtual std::string crypted(bool crypt) {return cppdb::crypt_db_value(mvalue, crypt); } ferencd@0: virtual value_renderer& decrypted(bool crypt) { mvalue = cppdb::decrypt_db_value(mvalue, crypt); return *this;} ferencd@0: std::string value() const {return mvalue; } ferencd@0: private: ferencd@0: std::string mvalue = ""; ferencd@0: }; ferencd@0: std::basic_ostream& operator << (std::basic_ostream& os, const text& tx); ferencd@0: ferencd@0: #define TEXT text ferencd@0: ferencd@0: // other types support ferencd@0: template class simple_type : public value_renderer ferencd@0: { ferencd@0: public: ferencd@0: typedef T type; ferencd@0: simple_type() = default; ferencd@0: simple_type(T t) : mt(t) {} ferencd@0: private: ferencd@0: T mt; ferencd@0: }; ferencd@0: ferencd@0: template <> class simple_type : public value_renderer ferencd@0: { ferencd@0: public: ferencd@0: typedef int type; ferencd@0: simple_type() = default; ferencd@0: simple_type(time_t t) : mt(t) {} ferencd@0: simple_type(const std::string& sv) : mt(stol(sv)) {} ferencd@0: std::string get_type() const {return _O("TIMESTAMP"); } ferencd@0: virtual std::string crypted(bool crypt) {return std::to_string(cppdb::crypt_number(mt, crypt));} ferencd@0: virtual value_renderer& decrypted(bool crypt) { mt = cppdb::decrypt_number(mt, crypt); return *this; } ferencd@0: std::string value() const {return std::to_string(mt); } ferencd@0: private: ferencd@0: time_t mt = 0; ferencd@0: }; ferencd@0: ferencd@0: template <> class simple_type : public value_renderer ferencd@0: { ferencd@0: public: ferencd@0: typedef int type; ferencd@0: simple_type() = default; ferencd@0: simple_type(int t) : mt(t) {} ferencd@0: simple_type(const std::string& sv) : mt(stoi(sv)) {} ferencd@0: std::string get_type() const {return _O("INTEGER"); } ferencd@0: virtual std::string crypted(bool crypt) {return std::to_string(cppdb::crypt_number(mt, crypt));} ferencd@0: virtual value_renderer& decrypted(bool crypt) { mt = static_cast(cppdb::decrypt_number(mt, crypt)); return *this; } ferencd@0: std::string value() const {return std::to_string(mt); } ferencd@0: private: ferencd@0: int mt = 0; ferencd@0: }; ferencd@0: ferencd@0: #define INTEGER simple_type ferencd@0: #define TIMESTAMP simple_type ferencd@0: ferencd@0: struct primary_key { const std::string modifier() {return _O("PRIMARY KEY"); } }; ferencd@0: struct not_null { const std::string modifier() {return _O("NOT NULL"); } }; ferencd@0: ferencd@0: template ferencd@0: struct defaults ferencd@0: { ferencd@0: defaults(const D& d) : md(d) {} ferencd@0: std::string get_modifier() const ferencd@0: { ferencd@0: std::string res = _O("DEFAULT "); ferencd@0: std::stringstream ss; ss << md ; return res + ss.str(); ferencd@0: } ferencd@0: private: ferencd@0: D md; ferencd@0: }; ferencd@0: ferencd@0: template class modifier_templ ferencd@0: { ferencd@0: public: ferencd@0: modifier_templ(){} ferencd@0: std::string get_modifier() const {return T().modifier();} ferencd@0: }; ferencd@0: ferencd@0: static const modifier_templ pk; ferencd@0: static const modifier_templ nn; ferencd@0: ferencd@0: #define PRIMARY_KEY pk ferencd@0: #define NOT_NULL nn ferencd@0: #define CURRENT_TIMESTAMP _O("CURRENT_TIMESTAMP") ferencd@0: #define DEFAULT(X) defaults(X) ferencd@0: ferencd@0: /* The actual warehouse keeping all the tables, columns and other elements */ ferencd@0: class cppdb_warehouse ferencd@0: { ferencd@0: public: ferencd@0: static cppdb_warehouse& instance(); ferencd@0: bool add_column(const Column* c); ferencd@0: bool add_table(const Table* t); ferencd@0: const Table* table(const std::string& tabname); ferencd@0: const Column* column(const std::string& colname); ferencd@0: private: ferencd@0: std::vector columns; ferencd@0: std::vector tables; ferencd@0: }; ferencd@0: ferencd@0: #endif // CPPDB