// file : odb/relational/context.hxx // copyright : Copyright (c) 2009-2015 Code Synthesis Tools CC // license : GNU GPL v3; see accompanying LICENSE file #ifndef ODB_RELATIONAL_CONTEXT_HXX #define ODB_RELATIONAL_CONTEXT_HXX #include #include #include namespace relational { namespace sema_rel = semantics::relational; namespace trav_rel = traversal::relational; enum statement_kind { statement_select, statement_insert, statement_update, statement_where // WHERE clause. }; // Index. // struct index { location_t loc; // Location of this index definition. std::string name; // If empty, then derive from the member name. std::string type; // E.g., "UNIQUE", etc. std::string method; // E.g., "BTREE", etc. std::string options; // Database-specific index options. struct member { location_t loc; // Location of this member specifier. std::string name; // Member name, e.g., foo_, foo_.bar_. data_member_path path; // Member path. std::string options; // Member options, e.g., "ASC", etc. }; typedef std::vector members_type; members_type members; }; typedef std::vector indexes; // Indexes in the above vector are in location order. // struct index_comparator { bool operator() (index const& x, index const& y) const { return x.loc < y.loc; } }; // Custom database type mapping. // struct custom_db_type { regex type; std::string as; std::string to; std::string from; location_t loc; }; typedef std::vector custom_db_types; class context: public virtual ::context { public: // Return true if an object or value type has members for which // the image can grow. If section is not specified, then ignore // separately loaded members. Otherwise ignore members that do // not belong to the section. // bool grow (semantics::class_&, user_section* = 0); // The same for a member's value type. // bool grow (semantics::data_member&); bool grow (semantics::data_member&, semantics::type&, string const& key_prefix); public: // Quote SQL string. // string quote_string (string const&) const; // Quote SQL identifier. // string quote_id (string const&) const; string quote_id (qname const&) const; // Quoted column and table names. // string column_qname (semantics::data_member& m, column_prefix const& cp) const { return quote_id (column_name (m, cp)); } string column_qname (data_member_path const& mp) const { return quote_id (column_name (mp)); } string column_qname (semantics::data_member& m, string const& key_prefix, string const& default_name, column_prefix const& cp) const { return quote_id (column_name (m, key_prefix, default_name, cp)); } string table_qname (semantics::class_& c) const { return quote_id (table_name (c)); } string table_qname (semantics::class_& obj, data_member_path const& mp) const { return quote_id (table_name (obj, mp)); } string table_qname (semantics::data_member& m, table_prefix const& p) const { return quote_id (table_name (m, p)); } public: string index_name (qname const& table, string const& base); string fkey_name (qname const& table, string const& base); // Custom database type conversion. // public: string convert_to (string const& expr, string const& sqlt, semantics::data_member& m) { string const& conv (current ().convert_expr (sqlt, m, true)); return conv.empty () ? expr : convert (expr, conv); } string convert_from (string const& expr, string const& sqlt, semantics::data_member& m) { string const& conv (current ().convert_expr (sqlt, m, false)); return conv.empty () ? expr : convert (expr, conv); } // These shortcut versions should only be used on special members // (e.g., auto id, version, etc) since they may not determine the // proper SQL type in other cases (prefixes, composite ids, etc). // string convert_to (string const& expr, semantics::data_member& m) { return convert_to (expr, column_type (m), m); } string convert_from (string const& expr, semantics::data_member& m) { return convert_from (expr, column_type (m), m); } // Return the conversion expression itself. // string const& convert_to_expr (string const& sqlt, semantics::data_member& m) { return current ().convert_expr (sqlt, m, true); } protected: virtual string const& convert_expr (string const& sqlt, semantics::data_member&, bool to); string convert (string const& expr, string const& conv); protected: // The default implementation returns false. // virtual bool grow_impl (semantics::class_&, user_section*); virtual bool grow_impl (semantics::data_member&); virtual bool grow_impl (semantics::data_member&, semantics::type&, string const&); // The default implementation uses the ISO quoting ('') and // escapes singe quotes inside the string by double-quoting // (' -> ''). Some (most?) database systems support escape // sequences. We may want to provide utilize that to support // things like \n, \t, etc. // virtual string quote_string_impl (string const&) const; // The default implementation uses the ISO quoting (""). // virtual string quote_id_impl (qname const&) const; public: virtual ~context (); context (); static context& current () { return *current_; } protected: struct data; typedef context base_context; context (data*, sema_rel::model*); private: static context* current_; protected: struct data: root_context::data { data (std::ostream& os): root_context::data (os) {} string bind_vector_; string truncated_vector_; }; data* data_; public: sema_rel::model* model; bool generate_grow; bool need_alias_as; bool insert_send_auto_id; bool delay_freeing_statement_result; bool need_image_clone; bool generate_bulk; bool global_index; bool global_fkey; string const& bind_vector; string const& truncated_vector; }; } #include #endif // ODB_RELATIONAL_CONTEXT_HXX