Click here to Skip to main content
15,897,519 members
Articles / Database Development / SQL Server

A scripted SQL query generation framework with IDE: SQLpp (v1.4)

Rate me:
Please Sign up or sign in to vote.
4.98/5 (47 votes)
12 Sep 200311 min read 416.5K   5.4K   133  
A helper framework for generation of SQL queries in C++ and Lua
#ifndef SQLPP_DATABASE_HPP
#define SQLPP_DATABASE_HPP

#include <sqlpp/config.hpp>
#include <sqlpp/utils.hpp>
#include <sqlpp/predefs.hpp>
#include <sqlpp/table.hpp>
#include <sqlpp/properties/id_property.hpp>
#include <sqlpp/properties/name_property.hpp>
#include <sqlpp/graph_types.hpp>
#include <sqlpp/adaptors/database_adaptor.hpp>
#include <iterator>

namespace sqlpp{

namespace graphs{
	using namespace boost;

	typedef property< 
		vertex_table_t, 
		properties::id_type
		> vertex_table_property_type;
	typedef property< 
		edge_ref_t, 
		ref_constraint_shared_ptr
		> edge_ref_property;

	typedef boost::adjacency_list<
		vecS,
		vecS,
		directedS,
		vertex_table_property_type,
		edge_ref_property
		> table_graph;

	typedef graph_traits< table_graph >::vertex_descriptor table_vertex_t;
	typedef graph_traits< table_graph >::edge_descriptor table_edge_t;
	typedef property_map< table_graph, boost::edge_ref_t >::type ref_map_t;
	typedef property_map< table_graph, boost::vertex_table_t >::type table_map_t;
	typedef property_map< table_graph, boost::edge_ref_t >::const_type ref_const_map_t;
	typedef property_map< table_graph, boost::vertex_table_t >::const_type table_const_map_t;
}

/** A database
 * \ingroup Core
 *
 * A database is composed of a tables and constraints. 
 *
 * \version 1.0
 * first version
 *
 * \date 07-23-2003
 *
 * \author Peli
 *
 * \par license
 * This code is absolutely free to use and modify. The code is provided "as is" with
 * no expressed or implied warranty. The author accepts no liability if it causes
 * any damage to your computer, causes your pet to fall ill, increases baldness
 * or makes your car start emitting strange noises when you start it up.
 * This code has no bugs, just undocumented features!
 * 
 * \todo 
 *
 * \bug 
 *
 */
class database :
	public boost::enable_shared_from_this<database>,
	public properties::id_property,
	public properties::name_property
{
protected:
	database(
		string_const_reference name_,
		adaptors::database_adaptor_shared_ptr adaptor_);

public:

	typedef std::pair< table_shared_ptr, graphs::table_vertex_t > table_vertex_type;
	typedef std::map< properties::id_type, graphs::table_edge_t > table_edge_map_type;
	typedef std::map< properties::id_type, table_vertex_type > table_id_map_type;

	class table_const_iterator;
	class table_iterator : 
		public std::iterator< 
			std::bidirectional_iterator_tag, 
            table_shared_ptr, 
            size_t>
	{
	public:
		table_iterator(){};
		table_iterator(table_id_map_type::iterator it_)
		:m_it(it_)
		{};
		table_iterator(table_iterator const& tit_)
		:m_it(tit_.m_it)
		{};

		bool operator ==( table_iterator const& it_ ) const		{	return m_it == it_.m_it;	};
		bool operator !=( table_iterator const& it_ ) const		{	return m_it != it_.m_it;	};
		table_iterator& operator++()							{	++m_it; return *this;};
		table_iterator operator++(int)							{	table_iterator it(m_it); ++it; return it;};
		table_iterator& operator--()							{	--m_it; return *this;};
		table_iterator operator--(int)							{	table_iterator it(m_it); --it; return it;};
		table_shared_ptr operator*() const						{	return m_it->second.first;	}
		table_shared_ptr operator->()	const					{	return m_it->second.first;	}

	private:
		friend table_const_iterator;
		table_id_map_type::iterator m_it;
	};
	typedef std::pair< table_iterator, table_iterator > table_iterator_range_type;

	class table_const_iterator : 
		public std::iterator< 
			std::bidirectional_iterator_tag, 
            table_shared_ptr, 
            size_t>
	{
	public:
		table_const_iterator(){};
		table_const_iterator(
			table_id_map_type::const_iterator it_
			)
		: m_it(it_) {};
		table_const_iterator(
			table_const_iterator const& tit_
			)
		: m_it(tit_.m_it)
		{};
		table_const_iterator(table_iterator const& tit_)
		: m_it(tit_.m_it)
		{};

		bool operator ==( table_const_iterator const& it_ ) const		{	return m_it == it_.m_it;	};
		bool operator !=( table_const_iterator const& it_ ) const		{	return m_it != it_.m_it;	};
		table_const_iterator& operator++()						{	++m_it; return *this;};
		table_const_iterator operator++(int)					{	table_const_iterator it(m_it); ++it; return it;};
		table_const_iterator& operator--()						{	--m_it; return *this;};
		table_const_iterator operator--(int)					{	table_const_iterator it(m_it); --it; return it;};
		table_shared_ptr const operator*() const				{	return m_it->second.first;	}
		table_shared_ptr const operator->()	const				{	return m_it->second.first;	}

	private:
		table_id_map_type::const_iterator m_it;
	};
	typedef std::pair< table_const_iterator, table_const_iterator > table_const_iterator_range_type;

	table_const_iterator_range_type get_tables() const;
	table_iterator_range_type get_tables();

	static boost::shared_ptr< database > create(string_const_reference name_);
	/** Creates a database
	 * Use this method to create a new database object.
	 * \throw sqlpp_exception memory allocation error
	 * \return a valid database shared pointer
	 */
	static boost::shared_ptr< database > create( 
		string_const_reference name_,
		adaptors::database_adaptor_shared_ptr adaptor_
		);

	adaptors::database_adaptor_shared_ptr get_adaptor() const;
	void set_adaptor( adaptors::database_adaptor_shared_ptr adap_ );

	/** Returns the number of tables
	 *
	 * \return number of table
	 */
	size_t get_table_size() const;

	/** Search for a table named name_
	 *
	 * \param name_ table name
	 * \return true if found
	 */
	bool contains_table(string_const_reference name_) const;

	/** Search for a table with id id_
	 *
	 * \param id_ table identification number
	 * \return true if found
	 */
	bool contains_table(properties::id_type id_) const;

	/** Search for a table named name_
	 *
	 * \param name_ table name
	 * \throw sqlpp_exception if could not find the table
	 * \return a valid shared pointer to the table
	 */
	table_shared_ptr get_table( string_const_reference name_) const;

	/** Search for a table with id id_
	 *
	 * \param id_ table id
	 * \throw sqlpp_exception if could not find the table
	 * \return a valid shared pointer to the table
	 */
	table_shared_ptr get_table( properties::id_type ) const;

	/**
	 *
	 * \param name_ table name
	 * \param field_prefix_ string added to all the fields in the table
	 * \throw sqlpp_exception table named name_ already exists
	 * \throw sqlpp_exception memory allocation error
	 * \return a valid shared pointer to the table
	 */
	table_shared_ptr add_table( 
		string_const_reference name_,
		string_const_reference field_prefix_ = "" );

	/** Create a query
	 * \throw sqlpp_exception memory allocation error
	 * \return a valid query shared pointer
	 */
	queries::select_query_shared_ptr create_query();

	/** Create the database SQL statement
	 *
	 * If forward_ is set to false, all constraints (Primary key, unique and references) are specified 
	 * outside the "create table" statement. Such behavior is better for SQL engine that do not support forward
	 * declaration.
	 *
	 * \param forward_ true if constraints are inlined in the table declaration
	 * \return 
	 */
	string_type get_create_statement() const;

    std::ostream& get_dot( std::ostream& out_);

	/** Returns reference constraints between two tables
	 * Finds the reference constraints from source_ to target_ 
	 *
	 * \param source_ referencing table (contains the foreign keys)
	 * \param target_ referenced table (contains the primary keys)
	 * \return a container of reference constraints
	 */
	ref_constraint_container find_refs( table_shared_ptr source_, table_shared_ptr target_) const;

    graphs::table_graph const& get_graph() const;
protected:
	friend table;
	void join_tables(ref_constraint_shared_ptr ref_);

private:
	table_id_map_type m_tables;
	graphs::table_graph m_table_graph;
	table_edge_map_type m_edge_map;
	adaptors::database_adaptor_shared_ptr m_adaptor;
};
typedef boost::shared_ptr< database > database_shared_ptr;
typedef boost::weak_ptr< database > database_weak_ptr;

};


#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Engineer
United States United States
Jonathan de Halleux is Civil Engineer in Applied Mathematics. He finished his PhD in 2004 in the rainy country of Belgium. After 2 years in the Common Language Runtime (i.e. .net), he is now working at Microsoft Research on Pex (http://research.microsoft.com/pex).

Comments and Discussions